Service Refactoring
How can a service be evolved without impacting existing consumers?
Table 16.4. Profile summary for the Service Refactoring pattern.
Problem |
The logic or implementation technology of a service may become outdated or inadequate over time, but the service has become too entrenched to be replaced. |
Solution |
The service contract is preserved to maintain existing consumer dependencies, but the underlying service logic and/or implementation are refactored. |
Application |
Service logic and implementation technology are gradually improved or upgraded but must undergo additional testing. |
Impacts |
This pattern introduces governance effort as well as risk associated with potentially negative side-effects introduced by new logic or technology. |
Principles |
Standardized Service Contract, Service Loose Coupling, Service Abstraction |
Architecture |
Service |
Problem
Subsequent to its initial delivery, unforeseen performance and business requirements may demand more from a service than it is capable of providing (Figure 16.10). Replacing the service entirely may be undesirable, especially when several consumer programs have already formed dependencies upon its established service contract.
Figure 16.10 Consumers of an existing service demand new requirements for which the service was not originally designed. The red symbols indicate the different parts of this service architecture that could be independently versioned.
Solution
Software refactoring is an accepted software engineering practice whereby existing software programs can be gradually improved without affecting the manner in which they behave. When applied to service design, this approach provides more opportunity for services to evolve within an organization without disrupting their existing consumers. As shown in Figure 16.11, with the application of this pattern the underlying logic and implementation of a service can be regularly optimized, improved, or even upgraded while preserving the service contract.
Figure 16.11 All parts of a service architecture abstracted by its contract can potentially be refactored without compromising existing consumer relationships. The service contract and the remaining, externally facing message processing agents (red) are not affected by the refactoring effort.
Application
Software refactoring practices allow programs to be improved through a series of small upgrades that continue to preserve their interfaces and overall behavior. By limiting the scope of these upgrades, the risk associated with negatively impacting consumers is minimized. The emphasis of software refactoring techniques is on the cumulative result of these individual refactoring steps.
This pattern can be more successfully applied when the service has already been subjected to the application of Decoupled Contract (401) and the Service Loose Coupling design principle. The separation of service logic from a fully decoupled contract provides increased freedom as to how refactoring can be carried out, while minimizing potential disruption to existing service consumers.
Impacts
The refactoring of existing service logic or technology introduces the need for the service to undergo redesign, redevelopment, and retesting cycles so as to ensure that the existing guarantees expressed in the service contract (which includes its SOA) can continue to be fulfilled as expected (or better).
Because already established and proven logic and technology is modified or replaced as a result of applying this pattern, there is still always a risk that the behavior and reliability of a refactored capability or service may still somehow negatively affect existing consumers. The degree to which this risk is alleviated is proportional to the maturity, suitability, and scope of the newly added logic and technology and the extent to which quality assurance and testing are applied to the refactored service.
Relationships
The extent to which Service Refactoring can be applied depends on how the service itself was first designed. This is why there is a direct relationship between this pattern and Service Normalization (131), Contract Centralization (409), and Decoupled Contract (401). The abstraction and independence gained by the successful application of those patterns allows services to be individually governed and evolved with minimal impact to consumer programs.
Furthermore, depending on the nature of the refactoring requirements, Service Decomposition (489), Concurrent Contracts (421), or Service Façade (333) may need to be applied to accommodate how the service is being improved.
Figure 16.12 Service Refactoring relies on several key contract-related patterns to ensure that refactoring-related changes do not disrupt existing service consumers.