by Thomas Erl

Working with SOA Design Patterns: Understanding Pattern Relationships

Sep 02, 20086 mins

SOA design patterns can and often should be interdependent. Implement a proper relationship between design patterns in order to make your SOA solution the best that it can be.

Design patterns have been part of the IT world for many years. An entire patterns community has even emerged to foster the evolution of new patterns and to establish guidelines around how patterns should be documented and related.

Yes, that’s right, patterns relate to other patterns. To work with design patterns, you need to understand these relationships. These relationships are especially important with respect to SOA because the scope of an SOA implementation tends to be larger than traditional applications. Therefore, SOA design patterns tend have a broader reach and, as a result, a greater impact.

Let’s start with the basics and get back to how one pattern can relate to another. There are many different types of relationships, but two of the most important ones pertain to dependency and support.

In order to apply one pattern, you may be required to apply (or have already applied) another. That’s a pretty straightforward dependency relationship, but it’s still helpful to understand why the dependency exists. For example, in the SOA design pattern catalog there is a pattern called Logic Centralization. It essentially establishes a rule whereby, for any given reusable body of solution logic, only one official service can exist. This reduces the risk of redundancy and maximizes reuse potential among services within a given domain. It also forms the basis of Agnostic Context, a design pattern that is applied to an individual service in order to give it a multi-purpose functional scope (because it is “agnostic” to any logic that is limited to a single-purpose).

Agnostic Context and Logic Centralization share the common goal of fostering reuse within services. While Logic Centralization establishes distinct units of logic, Agnostic Context ensures that any units with reuse potential will be limited to multi-purpose logic only. This way, they become purely reusable services.

In short, you could make a case that Agnostic Context is dependent on Logic Centralization because without centralizing distinct bodies of logic, it would be difficult to segment them into agnostic units. It wouldn’t make much sense to apply Agnostic Context until after the Logic Centralization pattern has been applied.

The other type of relationship we mentioned is where the application of one pattern supports another. So unlike the dependency relationship, there is no direct reliance in this case, which means that these types of relationships are easy to miss (as are their benefits). A supportive relationship simply means that one pattern helps realize the goals or ultimate purpose of another.

Let’s revisit our Logic Centralization example. The objective of this pattern is to foster reuse within services. However, the history of application integration has taught us that achieving connectivity via multiple point-to-point integration channels leads to a fragile architecture and, ultimately, an enterprise that is burdensome to evolve, especially in the face of business change.

What does this have to do with Logic Centralization? Well, imagine a service that encapsulates several databases and a legacy system. Even if we centralize the logic represented by the service, we are still not doing anything to prevent all of these underlying resources from being accessed directly via traditional-style integration channels. This is where Contract Centralization enters the picture.

The Contract Centralization design pattern limits external access to a service to its published technical contract (or interface or API), which means that the underlying resources cannot be touched by outside programs or applications (which we can refer to as service consumers), because the sole point of entry is the service contract.

This simple limitation increases service reusability in the long run. Over time, the service can be effectively evolved in response to business change by extending or even replacing its underlying resources while minimizing the impact of these improvements upon external service consumers (because they are not directly connected to the resources due to Contract Centralization). The greater the service’s longevity, the greater its long term reuse potential.

So while Logic Centralization does not need Contract Centralization, it certainly benefits from its application. In fact, when these two fundamental patterns are consistently applied to an inventory (collection) of services, they establish an environment highly capable of promoting business agility. Because services can be repeatedly reused, we are required to build less redundant logic with each new solution (reducing the time and cost of solution delivery). And because services can only be accessed via their contracts, we avoid forming integration channels that will be difficult to change. As a result, we end up with services that can be effectively reused and evolved in tandem with the business.

Of course, there’s much more to realizing the strategic goals of SOA than just applying these two patterns. However, it’s the foundation established by SOA design patterns such as these that is critical to achieving successful SOA. Even the most powerful, scalable, and sophisticated infrastructure can’t help you turn poorly designed services into high-value IT assets with repeatable return in an ever-changing business climate. Services need to be designed from the ground up to expect and adapt to change, which is what service-orientation is all about.

Before we conclude, let’s briefly introduce the concepts of a pattern application sequence and a pattern language. We just explained how Contract Centralization supports Logic Centralization, but when designing services, which pattern do you apply first? Although there is no absolute rule, you might have a preference. For example, when modeling a collection of services at the same time, it would probably make sense to begin with Logic Centralization in order to properly partition services into distinct units of logic. Then you can apply Contract Centralization so that each of these units (services) is given a technical contract as its official entry point.

What we’ve just described is a pattern application sequence consisting of two patterns applied in a specific order. A pattern catalog is ideally structured so that you can come up with many creative application sequences depending on your requirements, preferences, and constraints. Some catalogs even provide recommended pattern sequences where as much as individual patterns are considered proven design solutions, the application sequences themselves are also considered proven.

The freedom to combine patterns into endless sequences is what makes a pattern catalog more than just a documentation of design patterns; it’s what makes it a “pattern language.” As with any written language, you have words that can be strung together into sentences that are further combined into paragraphs, essays, and so on. Think of a pattern language in the same way. When you take a pen to paper you will, depending on your skills, create a great or not-so-great work of literature. Similarly, the key to working with a language of patterns also lies in your knowledge and insight of the patterns themselves. A big part of this insight can be gained by understanding how patterns relate.

Thomas Erl is the world’s top-selling SOA author, series editor of the Prentice Hall Service-Oriented Computing Series from Thomas Erl and editor of The SOA Magazine. He is also the founder of SOA Systems and the SOA Certified Professional program. Erl currently has 24 authors writing for his book series.