If you are a software developer, surely you've heard the buzz of late surrounding the term "Service Oriented Architecture" or SOA. SOA is often rated in surveys as being the number one initiative that CIOs plan on undertaking going forward. A number of vendors offer software tools to help "SOA-enable" existing IT applications or build new "SOA-based" applications. So what exactly is SOA? While there doesn't seem to be a universally accepted definition of SOA, there are two things that have generally come to be associated with SOA - Web Services and Business Process Management (BPM).
Most companies have a multitude of software systems in place related to different aspects of their business. These software systems often tend to be from different vendors, built for different platforms, and in different programming languages. As a result, there are two challenges companies continue to struggle with:
- how to move information from one system to another, and
- how to compose a business process that cuts across different systems.
Web Services standards have helped tremendously in addressing the first challenge. With Web Services, legacy applications can expose their functionality and invoke the functionality of other applications in a uniform, non-proprietary way using industry standards such as SOAP and HTTP. Information to and from Web Services is typically sent as simple XML text. XML is now a widely adopted and well understood lingua franca for data representation.
The second challenge of composing business processes that cut across multiple systems is addressed by BPM. Standards such as Business Process Execution Language (BPEL) enable the definition of business processes that can be composed from individual applications that expose their functionality as Web Services.
SOA has thus come to be associated primarily with integration of systems. But what if I am building a new application that has little to do with integration? Say I'm building a Business Intelligence (BI) tool for analyzing and reporting on data from a data warehouse and have no requirement to integrate any legacy systems, expose any Web Services, or provide any BPEL processes. Is SOA relevant in the design of such a system? Would I apply any SOA principles in architecting this application? Would it make sense to say that my new system's architecture is SOA-based? The answer to all of these questions is "Yes".
Although my BI system may not expose any Web Services or define BPEL processes, several principles which I believe are part of SOA are relevant in its design. The most important among them is the notion of architecting the system as loosely coupled modules that expose their functionality through well-defined service contracts. The service contracts define what the functionality of the module is, and is independent of how that functionality is implemented. The implementation of the functionality is provided by a module service implementer that honors the service contract. If all this sounds old and familiar it is because it is! This is something we have been doing for years - coding to interfaces. Defining Java interfaces that represent contracts and defining Java classes that implement these interfaces is a standard pattern. The implementation class can be changed without affecting any code that is written against the interfaces. So if this is old, what is new and SOA about it? What SOA adds, in addition to making this familiar design pattern a cardinal rule, is recommend how system state is represented and exchanged among module service implementers. A related SOA recommendation is keeping the mode of provisioning of a service separate and independent.
The mode of provisioning of a service relates to the "plumbing" associated with providing the service that includes server names and ports, wire/transport/communication protocols, and message formats. In a SOA-based design, the mode of provisioning is completely independent of the implementation of the service functionality. It should be possible to change the mode of provisioning without any change to the implementation of the service functionality. Further, in a SOA-based design, no assumptions are made regarding the runtime deployment of modules. Java-based modules could be co-located within the same JVM or be hosted in different ones. Non-Java-based modules are hosted in their appropriate runtime that have process/machine boundaries with the JVM hosting the Java modules.
During the execution of a business process, data that is exchanged among modules represents system state or parts thereof. This state data may need to be serializable across processes hosting disparate modules developed in different programming languages. Modules work with state data objects implemented in the module's programming language e.g. Java objects for Java-based modules, C# objects for an Office client module, etc. The implementation of the module's service functionality is independent of how state data objects are transferred across the module boundary to and from other modules. Given this, if state objects have any behavior associated with them, the behavior would have to be re-implemented in each module that is implemented in a different programming language, and that may consume these state objects - this is obviously undesirable. Further, unlike state, behavior is often different for different contexts such as user, application, and business process contexts. Also, there is often a need to externalize some behavior as declarative rules outside of procedural code to enable post-deployment changes by the customer to reflect his/her evolving business processes. In a customer deployment, changes in business processes are more likely to result in the need to change behavior rather than the shape of state objects. For example the structure of a Purchase Order changes very rarely while the Purchase Order approval rules may change frequently. For all of the reasons above, it is necessary for state objects to have no behavior associated, and for behavior to be separable, capable of being externalized, and dynamically updated. Note that accessor methods used to get to the contents of a state object do not constitute behavior since they do not change the state but merely access it.
So where is behavior defined, and who provides it? Behavior is provided only by module service implementers and is defined as part of service implementers' implementation of service contracts. As stated earlier, this behavior may change with context and may invoke declarative rules. Module service implementers produce and consume state objects. Service implementers have access to the state objects that are provided as inputs to them from calling modules, and have access to state objects that are available in the context in which they are executing. In contrast to state objects that do not have behavior, service implementers have behavior but do not hold state. State objects can inherit state from other state objects, and service implementers can inherit behavior from other service implementers. Note that service implementers may have local variables used during the execution of a service but the variables are local to that execution and do not represent system state.
The above brings out one of the key principles of SOA-based design that is often not well articulated or recognized - separation of state and behavior. Just as many countries hold dear the principle of separation of church and state, the separation of state and behavior is important to SOA-based design.