Service-Oriented Architecture Introduction, Part 1With the introduction of Web Services over the last year or so, there has been a renewed interest in service-oriented architecture (SOA). An SOA is an architecture that has special properties. It is an architecture made up of components and interconnections that stress interoperability and location transparency. The term service has been used for more than two decades. For example, leading transaction monitoring software has used the term "service" in the early 1990s. Many client-server development efforts in the 90s used the term "service" to indicate the ability to make a remote method call. Web Services has given the term service more prominence in the last few months. Services and service-oriented architectures are really about designing and building systems using heterogeneous network addressable software components. In this article, I will explore the evolution of SOA, make a case for SOA, and describe some of the properties of SOA.
Software Architecture in General
Before getting too far into the details of SOA, the term software architecture needs to be defined. Software architecture is a fairly new practice in the field of software engineering. The software architecture of a system consists of the large-grained structures of the software. It describes the components of the system and how those components interact at a high level. The interactions between components are called connectors. The configuration of components and connectors provide both a structural and a behavioral view of the system.
Brief History of Software Design
Over the last four decades, the practice of software development has gone through several different development methods. Each method shift was made in part to deal with greater levels of software complexity. The way we have managed complexity is to continuously invent coarser grained constructs, such as functions, classes, and components. We can think of these constructs as software "black boxes".
A problem arises when we try to group a large number of objects together. Although access to the objects is controlled through their interfaces, the granularity at the object level still makes dependencies between them difficult to control in a large system.
Introducing the component concept gives us a better way of managing these dependencies in large systems. A component is a smaller group of objects working together to provide a system function. For example, a claim, automobile and a claimant object can work together in a claims component to provide the claim function for a large insurance application. The claim component becomes another black box at the level of a large system function. The claim and automobile objects are not known to any other part of the system, except for the claim component. This means that no other part of the system can become dependent on these objects since they are completely hidden.
This is the point we are at today in software development. Technologies such as Enterprise Java Beans, .NET and CORBA are effective ways of implementing components. The method of component-based development has allowed developers to create more complex, higher quality systems faster than ever before because we have a better way of managing complexities and dependencies within a software system.
The Case for Service-Oriented Architecture
So are we done? In software engineering -- of course not! Now that we have developed all of these heterogeneous components for one system or another, we need to be able to use them together. But there is a problem: developers built some components using EJB, some CORBA, and many of the resources we need for our systems are on mainframe computers running COBOL. Using Enterprise Java Beans requires that method invocation be done via RMI. CORBA uses IIOP. And many times the component is located across the Internet, behind a firewall and the message cannot get through. Although each has tried to be interoperable with the other, small inconsistencies cause developers a lot of pain when trying to figure it all out.
In addition, even if we did not have these problems, the components still have to know too much about each other. For example, if I want to use a Claims component, I have to know not only what transport and payload type to use, I also need to know exactly where it is. I also need to have intimate knowledge about its interface so that if the interface changes, I have to change the way I call it. Since these components have network addressable interfaces and the number of clients can be large, this creates dependencies on an enormous scale. So how do we solve this problem?