A New Developer Mind-Set
by Chris Haddad

December 10, 2004

We are in the very early stages of a long but inevitable transition to the pervasive, network-centric platform. Enterprise application architects and developers must adopt a new mind-set, both in terms of how they build applications and the division of development labor necessary to support the needs of the business.

Service-Oriented Architecture (SOA) is a style of application design that creates flexible, adaptable, and distributed computing environments. SOA defines a set of principles, patterns, and practices for designing application functionality as shared, general-purpose services. The best practices enable developers to realize the SOA benefits of maximum service sharing, reuse, flexibility, and interoperability. Service design practices will allow organizations to create a more flexible architecture that can more readily adapt to changing business needs while holding down development costs. There are five main design themes that developers and architects must adopt: sharing and reuse, externalization, loose coupling, interoperable service contracts, and composite applications.

SOA is more about a mind-set than it is about technology. First and foremost, a developer must adopt an attitude that it is better to reuse an existing service than it is to build functionality from scratch. In those situations where no preexisting services are available, the developer should implement the service in such a way that other developers may reuse it in the future. Developers must constantly think about reusability and interoperability.

Building Business Processes
The real distinction between client/server architectures and SOA is in terms of how component interdependencies are factored. In client/server architectures, the focus is on building a specific application and factoring that application into logical components. In most circumstances, the developer fully expects to implement the entire application. In SOA, the focus is on building reusable services and then assembling those services to implement a business process. A given service may be used in any number of applications. In SOA, the developer expects to reuse as many existing services as possible and to implement only as much code as necessary to orchestrate the business process.

Each service should implement a particular business task and operates relatively autonomously. Developers can compose and recompose these services into orchestrated applications that implement a variety of business processes. In combination with the proper infrastructure, SOA can allow IT systems to respond rapidly to changing business conditions. Increasingly, core developers will build business logic and infrastructure services as reusable components, while business developers will act more like building contractors, by assembling (and then remodeling) process-oriented systems using standardized services as building materials.

The notion of general-purpose services that can be reused by multiple applications, rather than recreated for every application instance, is the essence of SOA, but it imposes several challenges. A given service implementation may require different operational semantics in terms of security, reliability, or transactions, for example, depending on the application context in which it's used. In traditional application architectures, developers typically implement these operational semantics within the application code, which reduces, if not eliminates, the reusability of the service.

SOA solves that problem by externalizing operational semantics. Instead of baking security semantics (such as identity and entitlement management) into a service, for example, developers rely on an external, general-purpose security framework that enforces authentication and authorization rules based on declarative policies that specify the required security semantics for a particular service within the context of a specific application. Likewise, instead of building their own transaction semantics into a service, developers rely on a general-purpose transaction framework, again governed by declarative properties.

Consequently, the ability to reuse the service increases exponentially. As new use cases arise—which may require different security and transaction semantics—external transaction and security frameworks can easily accommodate the new use cases, without requiring changes to the service code.

In this way, SOA changes the division of labor amongst developers by separating concerns. It also reduces development effort and leads to more robust applications. Infrastructure programming requires different skills from business logic development. Business developers should not need to be experts in security, reliability, and transactions. Given the complexity of these technologies, the likelihood that a business developer will make a mistake is frighteningly high. Likewise, security experts should not need to be experts in inventory control or payroll processing.

By separating responsibility for business development from infrastructure development, each class of developer can focus on what it does best. Business-oriented developers can leverage the work of more skilled systems-level programmers who understand how to implement complex infrastructure services.

Achieving Separation
In SOA, connections between the services that implement different pieces of application functionality are loosely coupled—meaning a given service doesn't have a strong dependency on another given service in the environment. Loose coupling is achieved by conforming to these design practices: stateless interactions, abstract service contracts, and coarse-grained service interfaces.

Typically, service interactions are stateless and nontransactional. Developers must use different development techniques, such as reliable, asynchronous message passing, to manage state and transactions in a loosely coupled architecture.

A loosely coupled service will separate the external interface of a service's external interface from its internal implementation. In a loosely coupled environment, interactions between services take place through a virtual boundary defined by the service contracts-such as Web Services Description Language (WSDL) definitions. These service contracts expose only those behaviors, logic, and context variables that a service is willing to grant to other services, leaving opaque all other aspects of a service's internal implementation. The separation allows changes to platforms' internal implementations of various functions while minimizing the need to revise the corresponding external interfaces. Implementing a data mapping and transformation layer in the middleware can achieve the separation.

Abstract services are created by using a design-and-development approach including: defining a service at the granularity of the business process; exposing service functionality through standard, document-oriented approaches, especially Simple Object Access Protocol (SOAP) Document/Literal style interfaces; and implementing end-to-end semantic interoperability among services through standard, agreed-upon schemas for inputting and outputting documents.

Coarse-grained interfaces involve defining service contracts that abstract the native object model and interfaces from a broad swath of functionality. Generally, coarse-grained interactions among services involve "chunky" conversations that package several function calls and responses into fewer but larger messages. By contrast, fine-grained service interfaces usually produce "chatty" conversations involving more but smaller messages among clients and services (see Figure 1).

Another best practice is to define Web services—hence, the associated WSDL definitions—to correspond to the granularity of activities and subprocesses within business processes. Developers should design Web services as coarse-grained, discrete tasks or orchestrations that each encompass a business process or substantial subprocess. In this way, architects can evolve the platforms underlying these services without needing to update the corresponding WSDL service contracts.

Because a key SOA goal is to establish a holistic architecture that unifies all application portfolio assets, Web services developers must be careful not to mirror their platforms' native object models, components, APIs, and other artifacts in their WSDL. When developers generate WSDL service definitions automatically from platform-specific object models, they inadvertently build the platform's native object model and methods right into the exposed WSDL portTypes.

By contrast, an interoperable Web service would start by developing WSDL from scratch and defining the WSDL in such a way that its elements don't correspond one to one with the object model, methods, and other artifacts of the underlying service platform. As an external interoperability contract, WSDL must remain stable through changes to the underlying application and platform.

Composite Applications
In SOA, applications don't really consist of tiers—at least not quite in the same sense as client/server application architectures define them. Applications are made up of a collection of loosely coupled services. Each service operates as a full peer to other services, and a communication fabric connects services.

A service may complete its entire task on its own, or it may call other services to perform various subtasks. A service that calls other services becomes the controller of its subtask. A composite application consists of a controller component that invokes the appropriate set of services to accomplish the desired business process.

The shift to a service-oriented mind-set will not be achieved overnight. Teams should establish design and development guidelines that focus on sharing, reusability, and interoperability. Guidelines should focus on defining policies related to application factoring, schema and WSDL definition, and design patterns. Additionally, processes and compliance tooling should be deployed to ensure conformance with the architecture principles.

About the Author
Chris Haddad is practice manager and senior consultant at the Burton Group. Contact Chris at chaddad@burtongroup.com.