Dr. Dobb's Journal July, 2004
Web services development tools are capable of rapidly producing web services from preexisting interfaces. However, not all interfaces are created equal. To quote the Service Interface pattern (http://msdn.microsoft.com/practices/type/Patterns/Enterprise/DesServiceInterface/) as defined by the Microsoft Platform Architectural Guidance (PAG) Group, "Many platforms make exposing the application functionality simple. However, this can lead to a poor decision in terms of granularity. If the interface is too fine grained, you can end up making too many calls to the service to perform a specific action. You need to design your service interfaces to be appropriate for network or out-of-process communication." In other words, while speed of development is important, the broader business and technical needs should be the main drivers of any web services you produce.
How do you avoid the trap of producing too-granular web services that don't fit with current and expected needs? IT organizations are recognizing the need to align their existing and under-development software development assets (SDAs) to the enterprise's strategic roadmaps to take full advantage of the promise of web services. Such alignment is key to defining and producing the "right" web services. Developers need to understand what assets exist, where they are located, and how each fits into the business and technical landscape. A model-based approach to web-services development gives you a way to enable existing SDAs as web services, and helps ensure that newly built components and applications expose well-defined service interfaces. This approach can be divided into four steps: Assess, Build, Locate, and Employ. In this article, we develop a .NET component by taking it through this four-step approach. In the process, we examine design patterns and best practices that ensure web services that perform well and provide the correct level of operation granularityand meet business needs. The example we present comes from CommunityAmerica Credit Union (CACU; http://www.cacu.com/) and the economies of scale gained by its implementation of a Service-Oriented Architecture (SOA) solution. The reusable SDA we examine is CACU's Customer Information System (CIS) component. Figure 1 presents this component in UML, showing its external interfaces without any of the proprietary implementation details involved in building the component.
The functional capabilities of this component are presented to users via a component interface containing a number of method definitions. These methods place dependencies on two supporting elements of the external component definitiona data transfer object (http://msdn.microsoft .com/practices/type/Patterns/Enterprise/DesDTO/) type used to interchange nonprimitive data with the component and a specialized exception that users of the component must handle when setting exchange rates into the component. The IFX System component enables the ability to talk to the financial system, regardless of platform or proprietary data format.
Typical IT organizations have any number of software development assets accumulated over the years. These assets range from the oldest "green screen" and client-server applications, to modern components and services. Assessing which of these assets are of value to the organization must keep in mind both business and technical perspectives. Issues that need to be taken into account during the assessment phase include:
At the outset, remember the 80/20 rulesome SDAs are obvious candidates for your initial cataloging efforts while other marginal assets are best left behind.
How does our example component fit against this assessment criteria?
Based on the assessment, it appears that the CIS component is an important asset that should be preserved and managed into the future. This leads us to the next stage of the model-based approach.
In the build phase, the task is to align the essential SDAs with the business roadmap. The end result of this effort is a ready reference that gives you the ability to see what aspects of your business architecture are already supported, identify redundancies, and see where gaps exist. Ultimately, effective use of this reference model lets you build web services that present the right level of information and interact with the right underlying business systems.
CommunityAmerica's business architecture team has defined a reference model roadmap for future banking platform channels that must access the Member System. These platforms require significant financial investment, and ROI must be maximized. Our business goals are to build reusable components to minimize rework and maximize reusability and functionality. Figure 2 is a UML diagram that illustrates how each system can reuse other critical system components.
In reality, component-oriented reference models such as this are not derived out of thin air. Behind this componentized view of the world is a series of business processes that drive internal and external interactions. Introducing a service-oriented architecture may serve as an impetus to review an enterprise's existing business processes, or a business-driven effort to revamp and modernize its business processes may necessitate an SOA and its underlying infrastructure to connect the abstracted business functions to their underlying heterogeneous applications.
Industry standards such as RosettaNet for supply chain management, ACORD for insurance, and IFX for financial services are increasingly influencing the business process definition. CommunityAmerica is developing an industry standard for the credit union market called "Credit Union XML" (CUXML), which is a member-centric XML model for describing the relevant data managed by the credit union industry. By standardizing on CUXML throughout CommunityAmerica's infrastructure, CommunityAmerica specifies a singular format across its reusable components. Each CUXML component then leverages a range of technologies to abstract proprietary or diverse standards that may exist across each developed solution; in this case, IFX.
Applying CUXML to its business processes, CommunityAmerica has begun to formally document those processes using UML use cases and activity diagrams. Figure 3 shows a UML activity diagram that documents a new loan process involving Customer Profile Inquiry and Asset Profile Inquiry. As you can see, the new loan activity directly relates to our CIS reference component. This sequencefrom business process to use case to activity diagram to component definitionmust be repeated numerous times to result in the example.
Returning to the UML reference model example, each of its classes represents a coarse-grained reference component that supports one or more interfaces whose operations are derived from use cases and activity diagrams. If you look into the CIS component in more detail, you see that its interfaces define a series of operations. Two of this component's four interfaces are detailed in Figure 4.
The operations defined here can be mapped against the methods defined by our component; see Table 1. Note the asynchronous reference in the Reference Component model of Table 1. The CIS component supports primarily synchronous operations. However, its call to the financial system will most likely be on a different system. The CIS component makes the IFX submit asynchronously so that locking resources are freed while waiting for the IFX system to respond. This improves load capacity of the web-services server. .NET provides ease of implementation of synchronous to asynchronous management as well as easy-to-use threading libraries for complex thread management.
As the development team is tasked to build out portions of the next-generation business architecture, CommunityAmerica will take advantage of previously built business reference models to search for candidate SDAs that can help them do their work more efficiently. Assume that your team has the responsibility to build out a web service supporting CIS operations. Your work activities flow as follows:
By leveraging an integrated client (such as Logidex) to manage contextual reference models that associate SDAs, CACU dramatically improves the speed and accuracy of this process. The seamless integration of Logidex and Visual Studio .NET manages the reusability of CACU's SDAs, minimizes the inefficiencies of duplication and rework, and maximizes ROI with every use.
Depending upon the area of the model being investigated, your team might find multiple assets that support a set of business capabilities. If so, at this point you need to determine whether you should select one of these assets for future development or to provide an encapsulation service that binds all of the existing assets together while ensuring consistent data and behavior across them. (If, for example, multiple CISs must be supported because of business merger activity in the past.) Or you might discover that no existing assets support a portion of your model, indicating that "green-field" development is needed to support some expanded business capabilities. Regardless of the outcome, your team has a better view of what is available for the next stage of the process.
The employ stage is where web-services development tools come into play. With the CIS example, we will likely retrieve our component assembly file from its repository location and deposit it into a Visual Studio project. We then use Visual Studio's web-service-generation capabilities to convert the component interface into a web service with an associated WSDL file, C# client proxy, and other artifacts.
As part of the employ phase, you have some decisions to make:
Here is where you can apply some useful design patterns and best practices (including borrowing some patterns from the J2EE world!) to make the web-service design and implementation better fit the technical and business needs. In fact, we have two server-side patterns staring us in the facethe Session Façade pattern (see Core J2EE Patterns: Best Practices and Design Strategies, by Deepak Alur et al., Prentice Hall PTR, 2003) and the Data Transfer Object pattern.
Reading from the Session Façade pattern, we see that a SessionBean "...manages the business objects, and provides a uniform coarse-grained service access layer to clients." There are two important points being made here, one of which is directly applicable to the specific problemSessionBeans (and by extension, .NET components) should be designed to manage underlying business objects. By introducing a CIS component following the Session Façade pattern, we now have a natural place to locate the business-process-oriented operations. By doing so, we have, in fact, created a coarse-grained componentone that presents a series of business services to clients without exposing those clients to the underlying complexity inherent in the implementation of those services.
Layered on top of the Session Façade pattern, the Data Transfer Object pattern provides an approach for consolidating the business information to be communicated between client and server. This pattern encourages the use of simple "data wrapper" classes to encapsulate business data exposed on the public interface of a coarse-grained component. These data-oriented classes can then be easily processed by the serializer/deserializer logic provided by the .NET web-services runtime frameworks.
Remote web-services clients typically interact with a service via object-oriented proxies (see Design Patterns: Elements of Reusable Object-Oriented Software, by Erich Gamma et al., Addison-Wesley, 1995) that are often generated by specialized web-services development tools from the WSDL document describing the service. These simple proxy classes provide individual methods for each of the operations described by the WSDL document. Each method directly invokes the underlying service (in this case, the coarse-grained component implemented by our CIS component) via the SOAP-based framework provided by the web-services runtime. The Microsoft PAG Group has codified this client/server relationship into a pair of patternsthe Service Gateway (representing the client) and the Service Interface (representing the server); see Figure 5.
In some cases, a simple Service Gateway is sufficient. There may be cases, however, where the client desires an additional level of decoupling from the services it invokes. For example, we might choose to build up a cache of recently accessed accounts to minimize remote activity and thus improve performance of our client, or we might want to build up a consolidated client view over multiple web services. The Business Delegate pattern (see Core J2EE Patterns) describes an approach that supports this level of isolation. Client activities occur solely through a client-side class, the Business Delegate, which in turn delegates any necessary remote invocations to the underlying Business Service (in this case, our generated SOAP client). Because the Business Delegate class is interposed between the client code and the SOAP client, we have the freedom to introduce client-side caching for frequently accessed information, consolidated service groupings with imbedded glue logic, or other useful features. The Business Delegate class can also serve as a stable interface point for the remainder of the client code, isolating any client-side changes that might result from changing server-side implementations to a single touch point.
In this article, we've laid out a real-life example of the importance of linking business requirements to executable SDAs and leveraging tools to maintain consistency between those two views of the world. By overlaying relevant design patterns into this example, we hope we've provided you with food for thought as you consider your next web-services project.
DDJ