Implementing the Strategy Pattern in Java
|
|
Main Page Technical Docs Design Patterns |
IntentThe Strategy Pattern described in the Gang of Four book is quite easy to implement in Java using their inner class concept. Because of this, the tradeoff between creating a new class versus switching behavior based on an if or switch statement is resolved in favor of the new class. Also Known AsDeath to Case Statements. MotivationIt is really common to have a class that needs to do one thing in one case, and something different in another case. For instance, a Button class might need to do "OKClicked" in one case, and "CancelClicked" in another case. Generally, rather than implement an entire subclass, the programmer instead uses a case or if statement to switch between behaviors. That is, the controller class for the dialog looks to see which button got clicked on, and then takes the appropriate behavior. This is because its simpler and more straightforward to use a case statement then to create an entirely new class just to signal which button got clicked. The frustration with this is that higher-level classes usually have the necessary knowledge, but that knowledge gets either lost or translated into an integer field which must be then retranslated. Creating a new class along the line of the strategy pattern would solve this problem, but it usually means that the higher level class must provide additional interface functions so that the strategy class can access the necessary pieces of the higher-level class. That's a lot of work just to distinguish between "OK" and "Cancel". With an inner class, the higher level class can tell the lower level class what action to take, preserving that knowledge and avoiding the case statements. Because the action is encapsulated in an inner class, the inner class can access everything in the higher-level class. Note that Objective-C and SmallTalk can implement this pattern by simply passing an object and method to the lower-level class for it to use as a callback. The Rhapsody/OpenStep architecture calls this a "target" and "action". You could do this in Java as well using the Reflection API, but inner classes are actually simpler, and have the value of doing compile-time type checking instead of run-time type checking. ApplicabilityI use this pattern almost everywhere I have a case statement, and a few places where I have an if statement as well. Really, anywhere I have a higher level class that creates a lower-level class where the lower level class handles part of the processing, but must then pass it up to the higher level class for further processing. StructureParticipantsIn progress Modelin Progress
CollaborationsIn progress
ConsequencesHow does the pattern support its objectives? What are the tradeoffs and results of using the pattern? What aspect of system structure does it let you vary independently?
ImplementationWhat pitfalls, hints, or techniques should you be aware of when implementing the pattern? Are there language-specific issues?
Sample Code and UsageIn progress Program Listing
Known UsesExamples of the pattern found in real systems. We include at least two examples from different domains. Related PatternsWhat design patterns are closely related to this one? What are the important differences? With which other patterns should this one be used?
|