Service-Oriented Architecture (SOA) as a design pattern has been gaining a lot of momentum lately. As technology advances and provides more and more power, SOA gradually shifts from a theory about how software should be developed to a case study in how software is developed.
SOA is considered to be the evolution of object-oriented programming by some people in the industry, whereas others consider it to be completely unrelated to the goals and purposes of object-oriented programming.
Before you can grasp the true definition of SOA, you need to understand the goals that drive this architecture. Achieving loose coupling among application components is a primary goal of SOA.
Loose Coupling and Dependencies
As time goes on and companies produce larger volumes of code, the need to reuse previously created functionality instead of rewriting it from scratch becomes more important. In fact, many times the cost of rewriting functionality instead of reusing it can mean the difference between a project that gets completed and a project that never makes it out of the first design meeting.
This introduces the concept of a dependency. Developers and designers alike often group the two different kinds of dependencies together, and this prevents the creation of the best application possible. There are two different kinds of software dependencies:
What often happens is that an artificial dependency is listed simply as a dependency or a requirement that must be fulfilled without any further discussion. This prevents the mitigation of this dependency and prevents the creation of the best application possible and maximum reuse of functionality.
What all of us strive for is the complete, or as nearly complete as possible, mitigation of the artificial dependencies within a system. This means that when examining dependencies, you need to make a clear distinction about which dependency is based purely on required functionality and which dependency is based on artificial limitations imposed on the feature consumer by the provider.
SOA as a Way of Life
SOA is an architectural pattern in which the main goal is to achieve loose coupling by reducing artificial dependencies within a system. Within SOA, there are services (also called providers) and consumers. A service is a discrete unit of work that accomplishes some task requested by a consumer. The loose coupling is achieved when the dependency that a consumer has on a specific provider is only that the provider accomplish a specific task, and that there are few or no artificial dependencies in the way. When loose coupling is achieved, the service can be consumed by any consumer that knows the agreed-upon message format to talk to the provider. Likewise, the consumer can use any provider of the same type.
In traditional object-oriented programming, the consumer and provider are very tightly coupled, and may even be part of the same class or library of classes. This is where SOA and OOP spread apart in philosophy. OOP traditionally indicates that data and the methods that process that data should be bound together, whereas SOA strives to separate the information from the processing of the information to allow one processor to perform its task on data from multiple consumers and one consumer to send its data to multiple processors without having any impact on the system.
The concept of reusable providers and consumers can become more apparent when applied to a real-world scenario. In the real world, we consume services because those services are either too costly or take too much time for us to do ourselves. In some cases, such as performing specialized tasks for which we have no aptitude, we would be completely unable to do the job ourselves, even if we had the time and money. For example, if I were to attempt to put a new roof on my house without getting the help of a professional, the results would be disastrous. This is called an "area of concern." Some existing services simply do the job better than the consumer could; you might consider some services to be "'experts."
At a hardware level, a device near and dear to the hearts of many developers can be considered a service provider: the Xbox. It provides a service of playing games. You, as the consumer, supply the information (games) to the service provider. As an output, you receive entertainment (and hopefully a high score). The service provider (Xbox) can provide the game-playing service to any input that meets the specified format. The input that you use on one Xbox can be used on any other Xbox because the service provider knows the format of the data being used as input. You can say that the Xbox is loosely coupled from the consumer in that you can play your games on any Xbox, and your Xbox can play games owned by any other consumer. The only dependency on the Xbox is a real dependency in that you must use the Xbox functionality in order to play an Xbox game.
Now that you know what SOA is, what its purpose is, and how similar models appear in everyday life, let's take a look at an example of SOA implemented in software.
In this hypothetical scenario, a company has decided to provide a unified storefront. It has purchased several smaller companies that used to sell products individually such as a bookstore, a DVD store, a CD store, and a company that sold consumer electronics online. The new, larger company wants to be able to provide all of the products of each individual child company in a unified storefront. In addition, the larger company wants to have several different sites that all share the same catalog and product fulfillment system so that they can be branded, styled, and customized for different companies.
Without SOA, creating a solution like this would be a daunting task. Even if a solution could be developed without SOA, it would be an extremely rigid and brittle solution that would break at the slightest attempt for expansion or modification because of the tight coupling and the numerous interdependencies.
Using Service-Oriented Architecture, the company decides to create a catalog service that can be used as an interface to the product catalogs of each of the individual child companies and a dispatcher service that is used to funnel requests for catalog information and features from the front-end applications to the appropriate catalog service based on the type of product. In addition, loosely coupled shipping and credit-card-charging services will be used for maximum scalability and growth potential. This allows each of the product catalog hosts to provide their catalog to any front-end store, and the front-end stores can work with any catalog. In addition, additional shipping providers, credit-card management systems, and even product catalogs can be added to the system with very little impact on existing code. Figure 33.1 illustrates this particular SOA case study.
Figure 33.1. Service-oriented architecture modelunified storefront.
This is by no means the only solution to the problem described. However, it does illustrate how the use of SOA and loosely coupled systems can dramatically reduce risk normally associated with a project of this size and can create an environment that is agile and able to cope with change and expansion without requiring a lot of rework and refactoring effort on the part of developers.