Рекомендация: Service Component Patterns
This guideline demonstrates a set of patterns that can be used in the development of Service Components in the realization of services.
Взаимосвязи
Связанные элементы
Основное описание

Introduction

In decomposing a service component into its constituent functional and technical components, we have delegated the functionality provided by the service component to fulfill the subsystem’s functional responsibilities. Functional components supply the business functionality required, while technical components provide generic functionality such as authentication, error handling, auditing, logging, etc which are operational and non-functional oriented.

A service model is a design-time artifact. As such, it does not deal directly with the implementation of services. However, the actual implementation of a service or set of services is strictly performed by a service component's realization of a service specification. The service specification provides the implementation contract; the technology or techniques used to implement the service are irrelevant as long as the contract is fulfilled. In the concept Service-Oriented Architecture, we introduced the following picture demonstrating the relationship between the services we identify and the components and objects that provide the implementation of these services.

 Diagram described in associated text

In this way, we can see how the RUP Design Model can be used to capture the design of the component and object layers, with implementation models and artifacts capturing details of the object layer and associated implementation and deployment artifacts. Important aspects of the relationship between the Service Model and the component design model are that the set of service specifications represent contracts that must be fulfilled, operations identified on specifications must be implemented as-is, and that consumers of services are using this same model to understand the interface and behavior of the services they expect to use. As such, there is a direct and in general a one-to-one relationship between the service specification and some implementation artifact that acts as the initial implementation entry point for the service.

For example, consider the following diagram of a service provider showing the details of model elements used in its definition.

Diagram is described in the textual content.

The key to the use of the service component is that it should be directly traceable to the service model. The easiest way to accomplish this is to make use of the fact that the service specification element is a UML Interface that can be realized by the service component, thus ensuring its conformance to the structural specification. In this way we would get the following result:

Diagram is described in the textual content.

It is now the responsibility of the component implementer to define a set of components and classes that provide the behavior of the resulting component.

Kinds of Service Components

Functional Components

The composition of these functional components into a larger-grained service component is not merely structural; it also involves the definition of flow, that is, the collaboration of the functional components to provide functionality to support the business processes. As we have seen earlier, the functionality of these business-related components is enabled through the services (implemented by the component’s finer level object or legacy system structure) defined.

It is important to note that this step includes traditional OOAD activities. We have a focused and well-partitioned scope to direct the object design. In traditional object-oriented design, we tend to create larger more dependent object graphs, whereas if subsystem analysis follows the identification of functional areas within the business, we have a very clearly defined scope to focus on and direct our design energies towards. These results in a set of more loosely coupled object models (class diagrams and sequence diagrams triggered by system use cases).

Technical components

The composition of technical components into larger-grained service components occurs in the same fashion as functional components. Technical components such as authentication, logging and reporting may be used across business processes.  These common components are needed to form the infrastructure to support the functional components.  One of the key variations across business processes is due to business rules as shown below in figure "Enterprise Component Pattern". These variations are typically captured during Variation-Oriented Design.

Service Component Patterns

Having said that the service component simply realizes the service specification does not provide the implementer with much assistance in going from a coarse-grained service definition to a set of fine-grained implementation classes and artifacts required to provide the behavior of the service. In this regard, it is common to rely on patterns that provide structure to the resulting service component, either as a starting framework or specific patterns to address particular policy requirements.

Pattern choice, driven by NFR, architecture [more]

Note that the additional stereotypes introduced here are described in the Artifact: Service Component.

Base Service Component Pattern

In defining the initial structure of a service, the following pattern is provided as a starting point for customization and completion.

Diagram is described in the textual content.

The elements of the pattern are:

  • Facade Component; the facade realizes the same interface as the service component itself and provides basic capabilities for message validation before passing the request on to the per-operation components for execution. In this case we stereotype the component as <<facade>> for clarification.
  • Per-Operation Component; given the granularity of services, it is useful in most cases to have a separate component/class for the implementation of each operation provided by the service.

The following demonstrates the composite structure view of this pattern. In this case, the facade is delegated to by the service component itself. As such, consumers calling operations on the service component are actually serviced by the facade component. Note that it would be possible to use UML 2.0 ports as well to expose the interfaces and make this delegation explicit using connectors.

Diagram is described in the textual content.

Single Operation Service Component Pattern

In some cases where services are identified in the Service Model with multiple operations, it is more appropriate to implement the operations individually as stand-alone services separating the logical service and physical service views. Such a pattern has advantages in terms of flexibility of sourcing, high availability, versioning, and evolution but does lose the notion of an interface to a service as a set of related operations.

Modeling service components according to this pattern has a single <<Service Component>> realizing a single interface with a single operation, all named according to common conventions and demonstrated below.

Diagram is described in the textual content.

In this case, as we mentioned, there is no direct realization of the original service specification by any one element in the pattern above. Therefore, it seems worthwhile to introduce an element in the model that can provide traceability back to the service specification. In the example below, we have introduced a component, stereotyped <<subsystem>> that is noted as implementing the service specification and also owning the elements described above.

Diagram is described in the textual content.

This pattern also does not introduce the <<facade>> component because consumers of the services are responsible for identifying the services they use.

Mediated Operation Pattern

Where there is the possibility that a service consumer's request may be routed to one of a selection of operation components for execution, it is possible to extend the pattern with a mediator to route these messages, as shown below. Note we stereotype the component/class as <<mediator>> for clarification. The exact mechanism used for mediation is undefined. A static set of implementations could be known ahead of time, a registry of some sort could also be used to map to the particular implementation based on the consumer, content of the request message, and so forth. This pattern is not intended for use with the single-operation pattern shown above.

Diagram is described in the textual content.

This also affects the composite structure view of the service component; as shown below, the mediator connection is shown from the facade which uses it to direct calls to the operation components.

Diagram is described in the textual content.

If a registry, external to the mediator itself, is used, it is not necessarily possible to show static usage dependencies from the mediator to the operation components or connectors between parts in the composite structure diagram. So, how can we model a dependency from the mediator to the mediated operation components? In the following diagram, we have introduced an interface to be implemented by each operation component. We can then model the usage from the mediator to the interface, as shown below.

Diagram is described in the textual content.

We also change the relationship in the composite structure diagram, including a new part typed by the interface, and denote the multiplicity between the mediator and operation components on the connector, as shown below.

Diagram is described in the textual content.

Data Access Components

Additionally, where service operations share common data requirements, it may be useful to highlight the specific components providing data management capabilities to the implementation. Note we stereotype the component/class as <<data access>> for clarification.

Diagram is described in the textual content.

The Enterprise Component Pattern

The Enterprise Component Pattern below shows the service component acting as a facade for the underlying functional and technical components. Services are exposed on the edge of the service component at the component facade. Requests for services on the facade are forwarded to a mediator which then routes the message to the appropriate functional or technical component.

Diagram described in associated text

Enterprise Component Pattern

The dependencies and needs of the functional components to the technical components, for the Rent-a-car example, are depicted below.

Diagram described in associated text

Rent-a-car reservation service component using the enterprise component pattern

The collection of subsystem component models is gathered into the functional component model which shows the reliance of the functional components on the technical components, and the inter-relationships between the functional components themselves. Leaf-level sub-processes that are assigned to the subsystem facade need to be specified as services the subsystem will provide. These sub-processes are supported and implemented through a finer grained set of system use cases encapsulated within the structure of the subsystem. The functional components are relied upon for the realization of the use cases. In turn the functional components depend on the technical components and utilities for their infrastructure needs.