Understanding Service-Oriented Architecture
Each system's software architecture reflects the different principles and set of tradeoffs used by the designers. Service-oriented software architecture has these characteristics Bieber and Carpenter 2001, Stevens, Service-Oriented, 2002, Sun Microsystems, Jini Technology Architectural Overview 2001):
- Services are discoverable and dynamically bound.
- Services are self-contained and modular.
- Services stress interoperability.
- Services are loosely coupled.
- Services have a network-addressable interface.
- Services have coarse-grained interfaces.
- Services are location-transparent.
- Services are composable.
- Service-oriented architecture supports self-healing.
|While Web services provide support for many of the concepts of SOA, they do not implement all of them. They do not currently support the notion of a contract lease. Also, no official specification provides QoS levels for a service. An organization cannot implement a complete service-oriented architecture given these limitations with Web services. In addition, service consumers can execute Web services directly if they know the service's address and contract. They do not have to go to the registry to obtain this information. Today, in fact, most organizations implement Web services without a registry. Consequently, the extent to which an organization implements an SOA with Web service varies greatly.|
Discoverable and Dynamically Bound
SOA supports the concept of service discovery. A service consumer that needs a service discovers what service to use based on a set of criteria at runtime. The service consumer asks a registry for a service that fulfills its need. The best way to explain dynamic binding and discover is to use an example. For example, a banking application (consumer) asks a registry for all services that perform credit-card validation. The registry returns all entries that support this. The entries also contain information about the service, including transaction fees. The consumer selects the service (provider) from the list based on the lowest transaction fee.
The consumer then binds the message to a transport type that the service expects and sends the service the request message over the transport. The service provider executes the credit-card validation and returns a message, whose format is also specified by the service description. The only dependency between producer and consumer is the contract, which the third-party registry provides. The dependency is a runtime dependency and not a compile-time dependency. All the information the consumer needs about the service is obtained and used at runtime.
This example shows how consumers execute services dynamically. Clients do not need any compile-time information about the service. The service interfaces are discovered dynamically, and messages are constructed dynamically. The removal of compile-time dependencies improves maintainability, because consumers do not need a new interface binding every time the interface changes.
This method of service execution is powerful. The service consumer does not know the format of the request message or response message or the location of the service until the service is actually needed. If the transaction fees for the credit-card validation services changed from minute to minute, consumers could still ensure that they received the best price.
Self-Contained and Modular
Services are self-contained and modular. One of the most important aspects of SOA is the concept of modularity. A service supports a set of interfaces. These interfaces should be cohesive, meaning that they should all relate to each other in the context of a module. The principles of modularity should be adhered to in designing the services that support an application so that services can easily be aggregated into an application with a few well-known dependencies. Since this is such an important concept when creating services, we will explain some of the principles of modularity and, in particular, how they apply to the creation of services. Bertrand Meyer (Meyer 1997) outlined the following five criteria for determining whether a component is sufficiently modular. These criteria apply equally well when determining whether a service is sufficiently modular.
The modular decomposability of a service refers to the breaking of an application into many smaller modules. Each module is responsible for a single, distinct function within an application. This is sometimes referred to as "top-down design," in which the bigger problems are iteratively decomposed into smaller problems. For instance, a banking application is broken down into a savings account service, checking account service, and customer service. The main goal of decomposability is reusability. The goal for service design is to identify the smallest unit of software that can be reused in different contexts. For instance, a customer call-center application may need only the customer's telephone number and thus need access only the customer service to retrieve it.
The modular composability of a service refers to the production of software services that may be freely combined as a whole with other services to produce new systems. Service designers should create services sufficiently independent to reuse in entirely different applications from the ones for which they were originally intended. This is sometimes referred to as bottom-up design. Sometimes, the composability and decomposability approaches to service design can create two different designs. The bottom-up approach is more focused on the application functions. The top-down design tends to be more focused on the business problem. It is important to use both methods to find the right interface for a service.
The typical design process starts as a decomposition exercise. When the designers get to a point at which they have exhausted the top-down design, performing a bottom-up analysis should validate the design. The bottom-up analysis starts by defining the significant scenarios that the modules need to support. For instance, in a banking application, a scenario is "deposit money into checking account." The significant scenarios will cover the important functional aspects of the modular design.
Once designers define the scenarios, they create sequence diagrams to illustrate the messages that flow between modules to satisfy the scenarios. Once the scenarios are satisfied, the designer can perform additional iterations of bottom-up and top-down analysis to tune the design of the modules.
The modular understandability of a service is the ability of a person to understand the function of the service without having any knowledge of other services. For instance, if a banking application implements a checking account service that does not implement a deposit function but instead relies on the client to use a separate deposit service, this would detract from the service's modular understandability. The modular understandability of a service can also be limited if the service supports more than one distinct business concept. For example, a service called CustomerCheckingAccount that mixes the semantics of both a customer service and a checking account service also limits modular understandability. The modular understandability is especially important for services, because any unknown consumer can find and use a service at any time. If the service is not understandable from a functional perspective, the person deciding whether to use the service will have a difficult time making a decision.
The modular continuity of a service refers to the impact of a change in one service requiring a change in other services or in the consumers of the service. An interface that does not sufficiently hide the implementation details of the service creates a domino effect when changes are needed. It will require changes to other services and applications that use the service when the internal implementation of the service changes. Every service must hide information about its internal design. A service that exposes this information will limit its modular continuity, because an internal design decision is exposed through the interface.
The modular protection of a service is sufficient if an abnormal condition in the service does not cascade to other services or consumers. For instance, if an error in the checking account service causes invalid data to be stored on a database, this could impact the operation of other services using the same tables for their data. Faults in the operation of a service must not impact the operation of a client or other service or the state of their internal data or otherwise break the contract with service consumers. Therefore, we must ensure that faults do not cascade from the service to other services or consumers.
In addition to the above criteria for modularity, two rules ensure that a service's modularity and independence are not compromised: Direct mapping and contracts and information hiding.
Page 3 of 8