Utility abstraction is a design pattern, applied within the service-orientation design paradigm, which advocates designing services[1] that provide cross-cutting[2] non-business[3] related functionality, which can be positioned as utility resources to automate multiple business processes.
To automate a business process, the required solution logic is based on the corresponding business work-flow and the business rules. Although the business specific logic can be derived from the business domain, however, in order to complete the automation of the business process, some general purpose logic is normally required that cannot be derived from the business domain. Such logic usually offers low level generic functionality that is commonly required to automate multiple business processes e.g. logging incoming service request messages for metering purposes. As different business processes are analyzed, the corresponding general purpose utility logic is identified and delivered as part of the main business processing solution logic (within the same service). Although this method works fine for fulfilling the short-term project requirements, it gets difficult to keep different services, each containing some level of utility logic, in-sync in the long run when it comes to making a change to the contained utility functionality e.g. due to an upgrade of the underlying technology resources (databases, legacy systems). On the other hand, it not only denormalizes the service inventory,[4] due to the redundancy of the utility logic, but also loses the opportunity of making such general purpose logic available for reuse to automate multiple business processes.
To address the above issues,[5] the Utility Abstraction design pattern dictates the separation of generic processing logic from the business process-specific logic into a separate group of services known as the utility services.[6]
This design pattern provides practical guidelines for designing the utility service layer as advocated by the service layers design pattern. These utility services are designed by analyzing the common processing requirements of business services (services that contain business process-specific logic) and then developing the required functionality represented by a meaningful functional context.[7] The functional contexts of utility services would tend to be more technology oriented as compared to entity services[6] as utility services mostly provide technology interfacing functionality[8] e.g. a wrapper service that talks to a legacy database or a service that provides data conversion functionality between different formats.[9]
It is important to understand that the functional contexts identified for the utility services need to correctly represent the functionality contained within utility services. This places an increased burden on correctly identifying such functional contexts which may prove difficult as the contained functionality is not directly linked to a particular business context and hence cannot be easily categorized into meaningful functional contexts. Some of the suggestions include:
The utility services are mostly used as helper services from multiple business process-specific logic, each having specific requirements, consequently it is better to design utility services that are based on targeted and specific functional contexts rather than vague functional contexts that pack a range of functions. This is important as it not only helps to keep the maintenance overhead of such services to a minimum but also increases the reuse potential of utility functionality because the service consumers can easily identify the required generic functionality as it is not bundled up in a broad functional context that does not correctly represent all of its contained functionality. The application of Canonical Expression[10] design pattern can further enhance the effectiveness of such targeted functional contexts by advocating the use of standardized naming conventions that correctly describe these functional contexts.
By moving the utility logic into separate services, inter-service communication is increased that can introduce latency as well as increased processing overhead. Similarly, due to the distribution of generic logic, the overall design of the service composition[11] will become complex and difficult to maintain.