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
Page 2 of 4
class Context
{
private Strategy strategy;
public Context(Strategy strategy)
{
setStrategy(strategy);
}
public void executeStrategy(int x)
{
strategy.execute(x);
}
public void setStrategy(Strategy strategy)
{
this.strategy = strategy;
}
}
The Context class in Listing 4 stores a strategy when it is created, provides a method to subsequently change the strategy, and provides
another method to execute the current strategy. Except for passing a strategy to the constructor, this pattern can be seen
in the java.awt .Container class, whose void setLayout(LayoutManager mgr) and void doLayout() methods specify and execute the layout manager strategy.
We need a client to demonstrate the previous types. Listing 5 presents a StrategyDemo client class.
public class StrategyDemo
{
public static void main(String[] args)
{
Context context = new Context(new ConcreteStrategyA());
context.executeStrategy(1);
context.setStrategy(new ConcreteStrategyB());
context.executeStrategy(2);
}
}
A concrete strategy is associated with a Context instance when the context is created. The strategy can be subsequently changed via a context method call.
If you compile these classes and run StrategyDemo, you should observe the following output:
executing strategy A: x = 1
executing strategy B: x = 2
Visitor is the final software design pattern to appear in Design Patterns. Although this behavioral pattern is presented last in the book for alphabetical reasons, some believe that it should come last due to its complexity. Newcomers to Visitor often struggle with this software design pattern.
As explained in Design Patterns, a visitor lets you add operations to classes without changing them, a bit of magic that is facilitated by the so-called double dispatch technique. In order to understand the Visitor pattern, we need first to digest double dispatch.
Java and many other languages support polymorphism (many shapes) via a technique known as dynamic dispatch, in which a message is mapped to a specific sequence of code at runtime. Dynamic dispatch is classified as either single dispatch or multiple dispatch:
print(). Suppose too that one of these classes is instantiated at runtime and its variable assigned to variable a. When the Java compiler encounters a.print();, it can only verify that a's type contains a print() method. It doesn't know which method to call. At runtime, the virtual machine examines the reference in variable a and figures out the actual type in order to call the right method. This situation, in which an implementation is based on
a single type (the type of the instance), is known as single dispatch.
a.print().)
Finally, double dispatch is a special case of multiple dispatch in which the runtime types of two objects are involved in the call. Although Java supports single dispatch, it doesn't support double dispatch directly. But we can simulate it.
David Geary's Java design patterns series on JavaWorld: Learn more of the Gang of Four patterns in Java code: