State pattern
From Wikipedia, the free encyclopedia
This article's factual accuracy is disputed. Please see the relevant discussion on the talk page. (March 2008) |
This article includes a list of references or external links, but its sources remain unclear because it lacks inline citations. Please improve this article by introducing more precise citations where appropriate. (April 2009) |
The state pattern is a behavioral software design pattern, also known as the objects for states pattern. This pattern is used in computer programming to represent the state of an object. This is a clean way for an object to partially change its type at runtime[1].
Take for example, a drawing program, in which there could be an abstract interface representing a tool, then concrete instances of that class could each represent a kind of tool. When the user selects a different tool, the appropriate tool would be instantiated.
Contents |
[edit] Interface Example
For example, an interface to a drawing tool could be
class AbstractTool { public: virtual void MoveTo(const Point& inP) = 0; virtual void MouseDown(const Point& inP) = 0; virtual void MouseUp(const Point& inP) = 0; };
That is, any tool needs to handle mouse motion and mouse-up and -down events. Then a simple pen tool could be
class PenTool : public AbstractTool { public: PenTool() : mMouseIsDown(false) {} virtual void MoveTo(const Point& inP) { if(mMouseIsDown) { DrawLine(mLastP, inP); } mLastP = inP; } virtual void MouseDown(const Point& inP) { mMouseIsDown = true; mLastP = inP; } virtual void MouseUp(const Point& inP) { mMouseIsDown = false; } private: bool mMouseIsDown; Point mLastP; }; class SelectionTool : public AbstractTool { public: SelectionTool() : mMouseIsDown(false) {} virtual void MoveTo(const Point& inP) { if(mMouseIsDown) { mSelection.Set(mLastP, inP); } } virtual void MouseDown(const Point& inP) { mMouseIsDown = true; mLastP = inP; mSelection.Set(mLastP, inP); } virtual void MouseUp(const Point& inP) { mMouseIsDown = false; } private: bool mMouseIsDown; Point mLastP; Rectangle mSelection; };
A client using the state pattern above could look like this:
class DrawingController { public: DrawingController() { selectPenTool(); } // Start with some tool. void MoveTo(const Point& inP) {currentTool->MoveTo(inP); } void MouseDown(const Point& inP) {currentTool->MouseDown(inP); } void MouseUp(const Point& inP) {currentTool->MouseUp(inP); } void selectPenTool() { currentTool.reset(new PenTool); } void selectSelectionTool() { currentTool.reset(new SelectionTool); } private: std::auto_ptr<AbstractTool> currentTool; };
The state of the drawing tool is thus represented entirely by an instance of AbstractTool. This makes it easy to add more tools and to keep their behavior localized to that subclass of AbstractTool
.
[edit] As opposed to using switch
The state pattern can be used to replace switch()
statements and if {}
statements which can be difficult to maintain and are less type-safe. For example, the following is similar to the above but adding a new tool type to this version would be much more difficult.
class Tool { public: Tool() : mMouseIsDown(false) {} virtual void MoveTo(const Point& inP); virtual void MouseDown(const Point& inP); virtual void MouseUp(const Point& inP); private: enum Mode { Pen, Selection }; Mode mMode; Point mLastP; bool mMouseIsDown; Rectangle mSelection; }; void Tool::MoveTo(const Point& inP) { switch(mMode) { case Pen: if(mMouseIsDown) { DrawLine(mLastP, inP); } mLastP = inP; break; case Selection: if(mMouseIsDown) { mSelection.Set(mLastP, inP); } break; default: throw std::exception(); } } void Tool::MouseDown(const Point& inP) { switch(mMode) { case Pen: mMouseIsDown = true; mLastP = inP; break; case Selection: mMouseIsDown = true; mLastP = inP; mSelection.Set(mLastP, inP); break; default: throw std::exception(); } } void Tool::MouseUp(const Point& inP) { mMouseIsDown = false; }
[edit] See also
[edit] External links
- Jt J2EE Pattern Oriented Framework
- State pattern in UML and in LePUS3 (a formal modelling language)
- State Pattern using Java : A Different Approach
[edit] References
- ^ Gamma, Erich; Richard Helm, Ralph Johnson, John M. Vlissides (1995). Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley. pp. 395. ISBN 0201633612.
|