Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
The Gang of Four's Design Patterns: Elements of Reusable Object-Oriented Software was a milestone in design pattern history. In Part 2 of his design patterns overview, Jeff Friesen focuses on the book and its 23 patterns. He first revisits the book's Strategy and Visitor patterns from a Java developer's perspective, then offers tips for learning all of the GoF patterns by successfully using Design Patterns as a reference manual. The article concludes with a summary of critiques of the GoF book and a warning about the perils of over-reliance on design patterns generally, which may be especially relevant for software developers new to programming.
In Part 1 of this three-part series introducing design patterns, I referred to Design Patterns: Elements of Reusable Object-Oriented Design. This classic was written by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides, who were collectively known as the Gang of Four. As most readers will know, Design Patterns presents 23 software design patterns that fit into the categories discussed in Part 1: Creational, structural, and behavioral.
David Geary's Java design patterns series introduced many of the GoF patterns in Java code. See the Resources section at the end of this article for a listing of Geary's articles on JavaWorld.
Design Patterns is canonical reading for software developers, but many new programmers are challenged by its reference format and scope. Each of the 23 patterns is described in detail, in a template format consisting of 13 sections, which can be a lot to digest. Another challenge for new Java developers is that the Gang of Four patterns spring from object-oriented programming, with examples based on C++ and Smalltalk, not Java code.
In this article I'll unpack two of the commonly used patterns -- Strategy and Visitor -- from a Java developer's perspective. Strategy is a fairly simple pattern that serves as an example of how to get your feet wet with the GoF design patterns generally; Visitor is more complex and intermediate in scope. I'll start with an example that should demystify double dispatch, which is an important part of the Visitor pattern. Then I'll demonstrate the Visitor pattern in a compiler use case.
Following my examples here should help you explore and use the other GoF patterns for yourself. In addition, I'll offer tips for getting the most out of the Gang of Four book and conclude with a summary of critiques of using design patterns in software development. That discussion could be especially relevant to developers new to programming.
The Strategy pattern lets you define a family of algorithms such as those used for sorting, text composition, or layout management. Strategy also lets you encapsulate each algorithm in its own class and make them interchangeable. Each encapsulated algorithm is known as a strategy. At runtime, a client chooses the appropriate algorithm for its requirements.
A client is any piece of software that interacts with a design pattern. Although typically an object, a client could also be code
within an application's public static void main(String[] args) method.
Unlike the Decorator pattern, which focuses on changing an object's skin, or appearance, Strategy focuses on changing the object's guts, meaning its changeable behaviors. Strategy lets you avoid using multiple conditional statements by moving conditional branches into their own strategy classes. These classes often derive from an abstract superclass, which the client references and uses to interact with a specific strategy.
From an abstract perspective, Strategy involves Strategy, ConcreteStrategyx, and Context types.
Strategy provides a common interface to all supported algorithms. Listing 1 presents the Strategy interface.
public interface Strategy
{
public void execute(int x);
}
Where concrete strategies are not parameterized with common data, you can implement them via Java's interface feature. Where they are parameterized, you would instead declare an abstract class. For example, right-align, center-align,
and justify text alignment strategies share the concept of a width in which to perform text alignment. So you would declare this width in the abstract class.
Each ConcreteStrategyx implements the common interface and provides an algorithm implementation. Listing 2 implements Listing 1's Strategy interface to describe a specific concrete strategy.
public class ConcreteStrategyA implements Strategy
{
@Override
public void execute(int x)
{
System.out.println("executing strategy A: x = "+x);
}
}
The void execute(int x) method in Listing 2 identifies a specific strategy. Think of this method as an abstraction for something more useful, like
a specific kind of sorting algorithm (e.g., Bubble Sort, Insertion Sort, or Quick Sort), or a specific kind of layout manager
(e.g., Flow Layout, Border Layout, or Grid Layout).
Listing 3 presents a second Strategy implementation.
public class ConcreteStrategyB implements Strategy
{
@Override
public void execute(int x)
{
System.out.println("executing strategy B: x = "+x);
}
}
Context provides the context in which the concrete strategy is invoked. Listings 2 and 3 show data being passed from a context to
a strategy via a method parameter. Because a generic strategy interface is shared by all concrete strategies, some of them
may not require all parameters. To avoid wasted parameters (especially when passing many different kinds of arguments to only
a few concrete strategies), you could pass a reference to the context instead.
Instead of passing a context reference to the method, you could store it in the abstract class, making your method calls parameterless. However, the context would need to specify a more extensive interface that would include the contract for accessing context data in a uniform manner. The result, as shown in Listing 4, is a tighter coupling between strategies and their context.
David Geary's Java design patterns series on JavaWorld: Learn more of the Gang of Four patterns in Java code: