Oliver Haase
Design Patterns
State
Description
‣
Object based behavioral pattern‣
Purpose: Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.‣
Also Known As: Object for StatesExample
‣
Consider a class TCPConnection with several different states: Established, Listening, Closed.TCPConnection responds differently to method invocations depending on its current state. E.g. the effect of an open
request depends on whether the connection is in its Closed state or its Established state.
Example - First Attempt
public class TCPConnection { private enum State {
ESTABLISHED, LISTENING, CLOSED;
}
private State currentState = CLOSED;
public void open() {
switch (currentState) { case ESTABLISHED:
...
break;
...
} }
public void close() {
switch (currentState) { case ESTABLISHED:
...
break;
...
} }
Example - First Attempt
‣
Hard to read.‣
Even harder if state consists of more than one variable.‣
Hard to discover each state transition.‣
What happens if we want to add a new state?•
Modify TCPConnection•
Add new case to every switch-case statement‣
Hard to test.‣
Better solution?Idea
‣
Encapsulate each case of the switch-case statement in its own state class.‣
The class TCPConnection maintains a state object that represents the current state of the TCP connection.‣
The class TCPConnection delegates all state-specific requests to this state object.‣
Whenever the connection changes state, theTCPConnection object changes the state object it uses.
Sample Structure
open() close()
acknowledge() TCPState
state.open()
open() close()
acknowledge() TCPEstablished open()
close()
acknowledge() TCPConnection
open() close()
acknowledge() TCPListen state
open() close()
acknowledge() TCPClosed
handle() State
state.handle()
handle()
ConcreteStateA request()
Context
handle()
ConcreteStateB state
General Structure
‣defines the interface of interest to clients
‣maintains an instance of a ConcreteState subclass that defines the current state
each subclass implements a behavior associated with a
state of the Context
defines an interface for encapsulating the behavior associated with a particular state of the Context
Applicability
Use the State pattern in either of the following cases:
‣
An object's behavior depends on its state, and it must change its behavior at run-time depending on that state.‣
Operations have large, multipart conditional statements that depend on the object's state.→ remember the smell of multipart conditional statements!
Who defines the state transitions?
‣
Context•
Context needs to know rules for state transitions.•
State transition all in one place.•
Context needs to know all State implementations.‣
State classes•
State object needs to modify its Context.•
Decentralization of state transitions.•
State needs to know its successor state.Pros & Cons
‣
Pro:•
Elimination of hard to read conditional statements.•
Easy to add further states.•
Simplified maintenance.•
Explicit state transitions.•
State objects can be shared.•
Easier testing of each individual state.‣
Con:•
Relationship with other Patterns
‣
State objects can be implemented as Flyweight (without intrinsic state).‣
State objects are often Singletons.Template Method
Motivation
Two classes have similar code. This leads to code duplication and duplicate effort if a change common to both classes
becomes necessary.
public class Coffee {
public void prepareRecipe() { boilWater();
brewCoffeeGrinds();
pourInCup();
addSugarAndMilk();
} }
public class Tea {
public void prepareRecipe() { boilWater();
steepTeaBag();
pourInCup();
addLemon();
} }
Idea
Pull similarities of both classes into a common abstract superclass and let subclasses implement only the differences.
Motivation
public class HotBeverage {
public final void prepareRecipe() { boilWater();
brew();
pourInCup();
addCondiments();
}
protected abstract void brew();
protected abstract void addCondiments();
private final void boilWater() {...}
private final void pourInCup() {...}
}
public class Tea extends HotBeverage { protected void brew() {...}
protected void addCondiments() {...}
}
public class Coffee extends HotBeverage { protected void brew() {...}
protected void addCondiments() {...}
}
Description
‣
Class based behavioral pattern‣
Purpose: Define the skeleton of an algorithm in anoperation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an
algorithm without allowing them to change the structure of the algorithm.
TemplateMethod() PrimitiveOperation1() PrimitiveOperation2()
AbstractClass
...
PrimitiveOperation1() ...
PrimitiveOperation2() ...
PrimitiveOperation1() PrimitiveOperation2()
ConcreteClass
General Structure
‣defines abstract primitive operations
‣implements a template method which defines the skeleton of an algorithm
implements the primitive operations to carry out subclass-
specific steps of the algorithm
Remarks
‣
Often used in frameworks and class libraries.‣
This principle (inversion of control) is often referred to as the Hollywood Principle: "Don't call us, we'll call you."‣
Template method should be final.‣
Superclass can implement hook methods which are optional to override for subclasses.‣
If there is a useful default implementation for the primitive operations, the superclass need not be abstract.Applicability
The Template Method pattern should be used
‣
to implement the invariant parts of an algorithm once and leave it up to subclasses to implement the behavior that can vary.‣
when refactoring is performed and common behavior is identified among classes. An abstract base class containing all the common code (in the template method) should be created to avoid code duplication.Real World Examples
Examples for Template Methods in Java:
‣ HttpServlet (Template Method is service())
‣ AbstractList (Template Method is addAll())
‣ SwingWorker (Template Method is execute())
‣ InputStream and OutputStream
Relationship with other Patterns
‣
Factory Methods get often invoked by Template Methods.‣
Strategy Pattern uses delegation to vary the wholealgorithm. Template Methods use inheritance to vary parts of the algorithm.