Design Patterns
239 pág.

Design Patterns


DisciplinaEngenharia de Software I4.656 materiais51.866 seguidores
Pré-visualização50 páginas
is AbstractTool:
 class AbstractTool is
 function moveTo(point) is
 input: the location point the mouse moved to
 (this function must be implemented by subclasses)
State pattern 172
 function mouseDown(point) is
 input: the location point the mouse is at
 (this function must be implemented by subclasses)
 function mouseUp(point) is
 input: the location point the mouse is at
 (this function must be implemented by subclasses)
According to this definition, each tool must handle movement of the mouse cursor and also the start and end of any
click or drag.
Using that base class, simple pen and selection tools could look like this:
 subclass PenTool of AbstractTool is
 last_mouse_position := invalid
 mouse_button := up
 function moveTo(point) is
 input: the location point the mouse moved to
 if mouse_button = down
 (draw a line from the last_mouse_position to point)
 last_mouse_position := point
 function mouseDown(point) is
 input: the location point the mouse is at
 mouse_button := down
 last_mouse_position := point
 function mouseUp(point) is
 input: the location point the mouse is at
 mouse_button := up 
 subclass SelectionTool of AbstractTool is
 selection_start := invalid
 mouse_button := up
 function moveTo(point) is
 input: the location point the mouse moved to
 if mouse_button = down
 (select the rectangle between selection_start and point)
 function mouseDown(point) is
 input: the location point the mouse is at
 mouse_button := down
 selection_start := point
 function mouseUp(point) is
 input: the location point the mouse is at
State pattern 173
 mouse_button := up
For this example, the class for the context is called Cursor. The methods named in the abstract state class
(AbstractTool in this case) are also implemented in the context. In the context class, these methods invoke the
corresponding method of the current state, represented by current_tool.
 class Cursor is
 current_tool := new PenTool
 function moveTo(point) is
 input: the location point the mouse moved to
 current_tool.moveTo(point)
 function mouseDown(point) is
 input: the location point the mouse is at
 current_tool.mouseDown(point)
 function mouseUp(point) is
 input: the location point the mouse is at
 current_tool.mouseUp(point)
 function usePenTool() is
 current_tool := new PenTool
 function useSelectionTool() is
 current_tool := new SelectionTool
Notice how one Cursor object can act both as a PenTool and a SelectionTool at different points, by passing the
appropriate method calls on to whichever tool is active. That is the essence of the state pattern. In this case, we
could have combined state and object by creating PenCursor and SelectCursor classes, thus reducing the solution to
simple inheritance, but in practice, Cursor may carry data which is expensive or inelegant to copy to a new object
whenever a new tool is selected.
Java
The state interface and two implementations. The state's method has a reference to the context object and is able to
change its state.
interface State {
 void writeName(StateContext stateContext, String name);
}
class StateA implements State {
 public void writeName(StateContext stateContext, String name) {
 System.out.println(name.toLowerCase());
 stateContext.setState(new StateB());
 }
}
class StateB implements State {
State pattern 174
 private int count=0;
 public void writeName(StateContext stateContext, String name){
 System.out.println(name.toUpperCase());
 // change state after StateB's writeName() gets invoked 
twice
 if(++count>1) {
 stateContext.setState(new StateA());
 }
 }
}
The context class has a state variable which it instantiates in an initial state, in this case StateA. In its method, it uses
the corresponding methods of the state object.
public class StateContext {
 private State myState;
 public StateContext() {
 setState(new StateA());
 }
 // normally only called by classes implementing the State 
interface
 public void setState(State newState) {
 this.myState = newState;
 }
 public void writeName(String name) {
 this.myState.writeName(this, name);
 }
}
And the usage:
public class TestClientState {
 public static void main(String[] args) {
 StateContext sc = new StateContext();
 sc.writeName("Monday");
 sc.writeName("Tuesday");
 sc.writeName("Wednesday");
 sc.writeName("Thursday");
 sc.writeName("Saturday");
 sc.writeName("Sunday");
 }
}
According to the above code, the output of main() from TestClientState should be:
monday
TUESDAY
WEDNESDAY
State pattern 175
thursday
SATURDAY
SUNDAY
External links
\u2022 State Design Pattern [4]
References
[1] Erich Gamma; Richard Helm, Ralph Johnson, John M. Vlissides (1995). Design Patterns: Elements of Reusable Object-Oriented Software.
Addison-Wesley. ISBN 0-201-63361-2.
[2] State pattern in UML and in LePUS3 (http:/ / www. lepus. org. uk/ ref/ companion/ State. xml)
[3] legend (http:/ / lepus. org. uk/ ref/ legend/ legend. xml)
[4] http:/ / sourcemaking. com/ design_patterns/ state
Strategy pattern
In computer programming, the strategy pattern (also known as the policy pattern) is a particular software design
pattern, whereby algorithms can be selected at runtime. Formally speaking, the strategy pattern defines a family of
algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently
from clients that use it.[1]
For instance, a class that performs validation on incoming data may use a strategy pattern to select a validation
algorithm based on the type of data, the source of the data, user choice, and/or other discriminating factors. These
factors are not known for each case until run-time, and may require radically different validation to be performed.
The validation strategies, encapsulated separately from the validating object, may be used by other validating objects
in different areas of the system (or even different systems) without code duplication.
The essential requirement in the programming language is the ability to store a reference to some code in a data
structure and retrieve it. This can be achieved by mechanisms such as the native function pointer, the first-class
function, classes or class instances in object-oriented programming languages, or accessing the language
implementation's internal storage of code via reflection.
Structure
Strategy pattern in UML
Strategy pattern 176
Strategy pattern in LePUS3 (legend [2])
Example
The following example is in Java.
// The classes that implement a concrete strategy should implement 
this.
// The Context class uses this to call the concrete strategy.
interface IStrategy {
 int execute(int a, int b); 
}
// Implements the algorithm using the strategy interface
class ConcreteStrategyAdd implements IStrategy {
 public int execute(int a, int b) {
 System.out.println("Called ConcreteStrategyAdd's execute()");
 return a + b; // Do an addition with a and b
 }
}
class ConcreteStrategySubtract