At some point during its lifetime a service might need to be enhanced or modified as a result of an external or an internal stimulus. The Service Refactoring design pattern addresses this issue in a manner so that the existing service consumers are not affected by the required change.
A service, from its inception until its retirement, will undergo some sort of change either to its underlying implementation or the service logic itself. This change could either be attributed to the increasing demands of its service consumers, with which it cannot cope anymore, or to the up-grading requirements of the underlying legacy systems. Whether the source of the change is internal or external to the service architecture, there is a requirement to address the change without breaking any dependencies between the service’s contract and its consumers. This change is best carried out by the application of the Service Refactoring design pattern that is based on the refactoring principles and techniques advocated by the object-oriented design paradigm. This pattern encourages smaller incremental changes in order to meet the overall objectives.
In an environment where the service consumers are tightly coupled to the service contract, any refactoring exercise, whether big or small, carries the risk of introducing inadvertent negative effects on the service consumers. So the key is to design the service in a decoupled manner right from the start and to ensure that all service consumers are dependent only on the service contract, i.e. they do not invoke the service indirectly via its logic or implementation. This could be achieved by the combined application of the Decoupled Contract, the Contract Centralization and the Service Façade design patterns. The Decoupled Contract pattern ensures that the contract is physically independent of the service logic. This decoupling can further be enhanced by introducing a façade component in between the service logic and its contract. This way, refactoring of the service logic would not impact the service contract. This could be supplemented by placing another façade component in between the service logic and the service’s underlying implementation so that any change in the underlying implementation, for example, the replacement of an obsolete legacy system, is absorbed by the façade component. The application of the Contract Centralization pattern ensures that any service interaction is only initiated through the service contract, thereby reducing the impacts caused by refactoring service logic.
The application of the Service Refactoring design pattern may result in service capabilities that are too fine grained and as a result stand a lesser chance of reuse. Such capabilities can be grouped into a single, coarse grained capability in order to increase the reuse potential of the service. However, to ensure that the service still honors its original contract, it may be necessary to concurrently support both the old and the new versions of the contract until the old version is phased out. The application of the Concurrent Contracts pattern might prove useful in this situation as it advocates the use of multiple contracts that are supported by the service at the same time. On the other hand, the application of the Service Refactoring pattern may result in a change to the functional context of the service, which may require moving a particular service capability out of the service contract into a new or an existing service. In this scenario, the refactoring impact could be addressed by the application of the Proxy Capability pattern so that the service only acts as a place holder for the removed capability and redirects the request to the correct service.
Like any other design pattern, the application of the Service Refactoring pattern needs to be carefully planned as its benefits are only materialized when the refactoring of the existing logic or technology is thoroughly tested in order to ensure that the service still operates at the same level as guaranteed by its technical contract as well as its SLA. Although this applies to any type of service, in case of agnostic services however, the application of this design pattern requires further testing and demands even more stringent governance efforts.
The Service Refactoring design pattern, when applied together with the Service Façade, the Contract Centralization and the Decoupled Contract design patterns, provides an ideal solution to a problem that every service is bound to run into at some stage during its lifetime. However, to be sure that we do not get any unintended side affects, a strict testing and governance regime needs to be in place.
The SOA Pattern of the Week series is comprised of original content and insights provided to you courtesy of the authors and contributors of the SOAPatterns.org community site and the book “SOA Design Patterns” (Erl et al., ISBN: 0136135161, Prentice Hall, 2009), the latest title in the Prentice Hall Service-Oriented Computing Series from Thomas Erl (www.soabooks.com).