
These days, it is getting harder and harder to ignore the object-oriented side of ABAP. If you are one of the many developers who have embraced this change, then perhaps you might be looking for ways to take your skills to the next level. Regardless of the discipline, one of the best ways to master a trade is to look at how senior practitioners go about solving particular problems. However, if you don’t have an OO guru sitting in the cubicle beside you, you might be wondering where you can go to learn these trade secrets. Fortunately, as it turns out, many of these best practices have been documented and left behind by some of the masters of the trade in the form of design patterns. In this blog series, I will introduce you to design patterns and show you how to use them to improve your designs.
The term “design pattern” was coined by Christopher Alexander, a noted architect whose book A Pattern Language: Towns, Buildings, Construction helped inspire software architects to document design approaches in terms of patterns. In his book, Alexander notes that “Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice”. Whether these solutions are fashioned from brick and mortar or from classes and interfaces doesn’t really matter. The point is that we can use this approach to document a solution to a problem in context.
The design pattern concept was first introduced to the software community in the classic software engineering text Design Patterns: Elements of Reusable Object-Oriented Software (colloquially known as the “Gang of Four Book”). In this book, four leading software engineers attempted to catalog a set of patterns that were informally known throughout the community. In an effort to bring some structure to the text, they documented these patterns in four parts:
Throughout the course of this blog series, I will introduce you to some of the more common design patterns documented in the Gang of Four book. To illustrate these solutions, I will try to show you how these solutions might be used to solve particular kinds of problems in ABAP. So, without further adieu, let’s begin our journey by looking at the Strategy pattern.
In some respects, the OO analysis and design (OOAD) process bares similarities to the classification process used by biologists to organize plants and animals. Here, we attempt to make sense out of a set of functional requirements by classifying the objects that make up a given problem space. A common tactic used to identify these classes is to read through a functional specification and underline all of the nouns. This approach, though flawed to a certain degree, is useful in taking a first pass through a set of requirements. On the other hand, it is easy to get carried away if you don’t have an open mind.
Technically speaking, a noun is a person, place, thing, or idea. Oftentimes, developers get hung up on those first three definitions, looking only at concrete object types such as business partners, plants, sales transactions, etc. However, this narrowed perspective limits you when modeling real world phenomena. After all, there are a lot of requirements that don’t fit into such neat little packages. For instance, what about algorithms? How do we classify those?
Normally, algorithms are classified as a type of behavior and associated with one or more classes in the form of methods. However, in certain cases, this design approach violates a core OO design principle in that it reduces the cohesiveness of the class(es) in question. Here, the term “cohesiveness” refers to how strongly related and focused the various responsibilities of the class are. In other words, does the algorithm fit within the class? Or should it stand on its own?
To answer these questions, let’s take a look at an example from the sales and distribution domain. Let’s imagine that you want to develop a sales contract application. As you would expect, one of the core classes in this application would be a "Contract" class. Of course, there are many different types of contracts. There are fixed price contracts, cost-plus contracts, basic ordering agreements, etc. At first, you might be inclined to model these differences by developing a class hierarchy like the one depicted in the UML class diagram below.
Looking at the UML class diagram above, you can see some problems with this approach. In this simple diagram, we have only shown a subset of the classes that might be derived. In reality, the class hierarchy might end up extending several levels down depending upon how many different contract types the application needs to support. This kind of fine-grained specialization results in designs that are brittle and hard to maintain.
So, you might ask, how should we proceed differently? Well, before we investigate alternative designs, let’s look at a few common themes in the Gang of Four book (I’m paraphrasing here):
Looking back at our sales contracts example, let’s see if these concepts can help guide us towards a better solution:
When you put all this together, you arrive at the Strategy pattern. In the Gang of Four book, the definition of the Strategy pattern is as follows:
Define a family of algorithms, encapsulate each one, and make them interchangeable.
Strategy lets the algorithm vary independently from clients that use it.
The UML class diagram below shows a revised design architecture for our contracts example using the Strategy pattern. As you can see, we have factored out the various contract-specific calculations into a separate class hierarchy underneath the abstract base class ContractValuation. Within this hierarchy, we can reuse existing algorithms to derive specialized value calculations such as the one required for a cost-plus incentive contract. In this way, the Contract class can vary independently from the various calculations (which may change more frequently). Also, by splitting the calculations out, we give ourselves more room to maneuver. This makes it possible to mix-and-match valuations at runtime, re-use calculation logic in other areas of our application, etc.
Hopefully by now you have an appreciation for the Strategy pattern. Generally speaking, you will want to use the Strategy pattern when you come up with a design in which you have many related classes that differ only in their behavior. Other warning signs that might indicate a fit for the Strategy pattern include situations where you find yourself writing a lot of CASE statements or doing a lot of “copy-and-paste” coding. In an upcoming blog entry, I will show you how you can blend the Strategy pattern with another pattern to simplify the integration process