An Introduction to Services From This Coder's Perspective

First, there is the question of “what is a Service?”  

W3C defines a web service as:
a software system designed to support interoperable machine-to-machine interaction over a network.”[1]

They go on to specify some specific technologies mandated by this particular standard and the role a service plays:
“The purpose of a Web service is to provide some functionality on behalf of its owner -- a person or organization."
This definition describes the infrastructure, focusing on how we deploy services and what purpose they serve right now to MBAs.  It is as though they are defining a program as "a sequence of machine instructions that perform mathematical or logical operations on behalf of a computer operator”.  I want a definition that tells me how to address the technical questions that emerge and provides guidance on how we will be writing and employing services going forward.  My current personal definition is:
A Service is an Object bound at run-time by a networking protocol.

Note that I mean “object” here under Alan Kay’s definition [2] and not in the particular sense that the word is used any specific language like Java or C++.  Despite varying dynamics, all service frameworks encapsulate some combination of data and behavior (not necessarily *well*, of course, but when they fail it is usually clear from the pain that follows.)  They hide implementation details while fulfilling either implicit or explicit contracts in response to messages sent by other services.[3]

The interesting change from current Object-Oriented programming paradigms is that they also encapsulate the location they are executing and the provider of the object.  Because we bind to the specific implementation at runtime using a networking protocol of some kind, the object can be running on any machine, virtual or physical, anywhere reachable by that protocol.  I don’t think this fundamentally changes the paradigm any more than dynamically linked libraries did, but it is really, really cool.

The practical question is: how do we use them?

To use a service we compose the message we want to send the object in the format it understands, and then pass it to the object using whatever networking protocol that service employs.  We either accept the response (under a procedural framework), or accept messages of our own if we want to receive a response under an Actor model.  To write a service we accept certain messages, documented in either or both human and machine-readable frameworks, and fulfill the promised responsibilities, replying or sending messages of our own as appropriate.
Currently the most common technologies are Simple Object Access Protocol (SOAP web services) and REpresentative State Transfer (RESTful web services), but the details will depend on what service you are talking to anyway, so you might as well look them up when it become relevant.  Who knows how long these will remain the dominate technologies anyway; network-location agnostic objects are likely to outlast any specific encoding mechanism we are using today.

Finally, when should we be writing services?

This is rather more complicated, as it will depend on the performance implications of current technologies and other business concerns.  However, since good service design is primarily just good object-oriented design and it is always possible to use API-mediated object communication without actually deploying things as services, I think the answer is "whenever there isn't a clear rationel not to."  Writing services enforces loose coupling (because passing data is expensive), makes reuse trivial and rewards tight cohesion.  Of course, we're all doing all of that anyway *cough*, but it can't hurt to have a little extra incentive.  If we write components as services in the first place, it then becomes trivial to deploy things as web services whenever we find we want location-independent messaging, easy caching or other advantages.

So, that’s pretty easy right?  Services are simply a new application of an age-old mechanism for handling complexity: split a very complex problems into smaller pieces, each of which is solve-able without understanding the mechanisms, actors or locations that solve the others. I might wish that we'd found a word that wasn't quite so over-used, but the idea is sound.

[2] "OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things.”

[3] Perhaps the one non-obvious implication of this definition is that any program that engages in two-way communicates with a web service is also a service, whether it believes itself to be or not.