SOA: Are We Reinventing the Wheel?

by Nick Simha
05/03/2006

Introduction

If you have been in the IT field for a while, you can't help but get the feeling of déjà vu when you hear vendors pitching new technologies. If the buzz and hype around Service Oriented Architecture (SOA), makes your head spin, you are not alone. In a recent meeting, one participant who used to code in COBOL asked what was different between SOA and what he did with COBOL copybooks. I have never used COBOL copybooks, but having seen many technologies come and go, I can empathize with the question. In this article, I explain the primary motivation behind SOA and how technology has evolved to support SOA. I will keep my discussion at a conceptual level and refer to other publications at the end for those who want to delve deeper.

Barriers to Reuse

One of the holy grails of software development has always been reuse. This is fairly obvious: If you have a piece of code that already does what you want, you will of course be more productive if you don't have to rewrite it or maintain it in multiple places. However, reuse is neither easy nor automatic. You must first organize or write your code in such a way that it can be reused. You must then know that there is a piece of code that can be reused. In terms of organizing your code, different programming languages have built-in support to enable reuse in different ways. Procedures and functions are the basic units that most programmers are familiar with. Object-oriented languages such as C++ and Java additionally provide means to define and extend custom types or classes. The basic idea behind these features is encapsulation (that is, you only access functionality through some well-defined interface, and the implementation is a black box to you). These features have their uses and merits, but they also have several limitations when it comes to the question of enabling larger scale reuse.

First, these programming language artifacts are at a very low level and can only be effectively reused by a programmer who has intimate knowledge of what it does.

Second, there is really no easy way to discover what reusable assets exist even within the same project team let alone an enterprise.

Finally, code at this level is not network enabled, meaning I can't just call this code across machine boundaries nor is it transparently reusable from a different programming language. As an example, if I have a pricing module already written in C++, I can't just invoke it from Java without going through hoops.

The point I want to make is that these features certainly have their use, but reuse at this level really means cut and paste code, which is error prone and not scalable.

Toward Reuse

The notion of service was born to address some of these reuse issues. CORBA, a standard from the Object Management Group (OMG), was perhaps the first comprehensive effort to address reuse with a standards-based distributed computing model.

The idea was to formally enforce the notion of encapsulation through an abstract interface and provide a set of infrastructure services that could be leveraged by these services (or objects in CORBA terminology). The interface was defined using a language called IDL (Interface Definition Language), and mappings were defined for various programming languages. A service could be described with this language. To use a particular service, all you needed was the IDL; the detail of how the service was actually implemented was not needed. These services were also network enabled. That provided a convenient means to cross hardware, language, and network boundaries.

CORBA additionally defined a rich set of infrastructural services such as directory service (called naming) to register and discover objects, trader service to discover objects based on advertised attributes, notification service for asynchronous communication, transaction services, and more. So now services could be quickly built since they could leverage these infrastructural services. These services could also be easily reused across the various boundaries described earlier. The other distributed component models like DCOM from Microsoft and J2EE followed a more or less similar model to building and consuming services.

What Exactly Is SOA?

We're now ready to define Service Oriented Architecture or SOA. Unfortunately, multiple and sometimes competing definitions of SOA exist. Many of the definitions tie a particular technology (notably Web services) to them or make a particular characteristic (for example the invocation style) part of the definition. Instead of giving yet another definition, I will give a few existing definitions that I think capture the essence of SOA without tying them to a particular technology stack. But first let's look at the word "service" in Service Oriented Architecture.

Defining service in SOA

Service is an overloaded term with few good definitions. A service is a function capable of being invoked in a distributed manner, is well defined, self-contained, and does not depend on the context or state of other services. Let's look at some of these characteristics that make up the definition of a service.

Invokable in a distributed manner: This is important since we cannot make the assumption that a piece of functionality would be in the client environment.

Well defined: As discussed earlier, one of the challenges of reuse at the programming-language level is the difficulty of discovering the reusable assets and using them across various technology boundaries. A service should be capable of describing and registering itself in a well-known directory, and the client wishing to invoke the service should be able to invoke the service based solely on the registered information.

Self contained: The semantics of an operation should be determined by the information in the incoming operation and the state of the service. There should be no dependence on the state or context of some other service. This isolation makes it easier to understand the functionality provided by a service and therefore reuse it.

SOA definition

Let's now look at a few different definitions of SOA. The W3C defines SOA "as a set of components which can be invoked, and whose interface descriptions can be published and discovered." I personally don't like the use of the word component in this definition, because component is such an overloaded term and brings to mind specific things like ActiveX, EJBs, and so on. However, if we substitute service for component, this definition is reasonable.

ZapThink, an industry analyst firm, defines SOA as "an architectural discipline that centers on the notion that IT assets are described and exposed as Services. These Services can then be composed in a loosely-coupled fashion into higher-level business processes, which provide business agility in the face of IT heterogeneity." I like this definition a lot better because it defines SOA in terms of IT assets that are broader in scope. Also, it points out an important characteristic of SOA—loose coupling (more on this later)—and mentions the benefits of SOA.

A final definition is from the SOA Technology Center on BEA's dev2dev site where SOA is defined as "a design methodology aimed at maximizing the reuse of application-neutral services to increase IT adaptability and efficiency." This is a good business-level definition of SOA: It emphasizes the fact that it is more than just technology artifacts like interfaces and protocols; rather it is a design methodology that has the explicit aim of maximizing reuse. I would add another piece to this definition: It is not only the design methodology, which can be thought of as the front-end piece, but it is also the methodology that involves the entire lifecycle of a service—designing it, deploying it, maintaining it, and finally retiring it.

These three definitions hopefully have given you a flavor of what SOA is and what its goals are. Before I move to the next section, I want to touch on an important characteristic of SOA—loose coupling. Coupling is the degree to which components depend on each other. On one end of the spectrum you can have services that are designed together and are therefore tightly coupled; on the other end, you have services that can be discovered and dynamically used on the fly. Loose coupling is desirable because it reduces dependencies between services or components and allows things such as easy substituting or upgrading of services.