CR的代码文本

all for learning about the world
  订阅 订阅  :: 管理

状态模式的c++实现

Posted on 2011-04-08 18:21  mumuliang  阅读(1419)  评论(4编辑  收藏  举报

Element

State

StateSet,一组state

Console,管理一组Element

代码有功能瑕疵。未实现activated元素间的互斥。

 

View Code
#include <iostream>
#include 
<vector>
#include 
<string>
#include 
<map>

inline 
void line(std::string str)
{
    std::cout 
<< str << std::endl;
    
return
}


enum StateID
{
    WAITE,
    READY,
    ACTIVATED,
    MOVING,
    ZOOMING    
};

std::
string getStateName( StateID id )
{
    
switch (id)
    {
    
case WAITE:
        
return "WAITE";
    
case READY:
        
return "READY";
    
case ACTIVATED:
        
return "ACTIVATED";
    
case MOVING:
        
return "MOVING";
    
case ZOOMING:
        
return "ZOOMING";

    }
}

class State
{
public:
    State(){}
    
virtual ~State(){};

    
virtual void onTouchDown( void ) = 0;
    
virtual void onTouchMove( void ) = 0;
    
virtual void onTouchUp( void ) = 0;
};

class StateSet
{
public:
    StateSet( 
void ){ line("class StateSet");}
    
virtual ~StateSet( void )
    {
        
if (_waitState)
        {
            delete _waitState;
        }
        
if (_readyState)
        {
            delete _readyState;
        }
        
if (_activatedState)
        {
            delete _activatedState;
        }
        
if (_movingState)
        {
            delete _movingState;
        }
        
if (_zoomingState)
        {
            delete _zoomingState;
        }
        line(
"class ~StateSet");
    }

    
void setState(StateID id, State* state)
    {
        
switch (id)
        {
        
case WAITE:
            _waitState 
= state;
        
case READY:
            _readyState 
= state;
        
case ACTIVATED:
            _activatedState 
= state;
        
case MOVING:
            _movingState 
= state;
        
case ZOOMING:
            _zoomingState 
= state;
        }
    }

    State
* getState(StateID id)
    {
        
switch (id)
        {
        
case WAITE:
            
return _waitState;
        
case READY:
            
return _readyState;
        
case ACTIVATED:
            
return _activatedState;
        
case MOVING:
            
return _movingState;
        
case ZOOMING:
            
return _zoomingState;
        }
    }

protected:
    State 
* _waitState;
    State 
* _readyState;
    State 
* _activatedState;
    State 
* _movingState;
    State 
* _zoomingState;
};


enum EventID
{
    DOWN,
    MOVE,
    UP
};
EventID getEventID( std::
string name)
{
    
if (name == "down")
    {
        
return DOWN;
    }
    
else if (name == "move")
    {
        
return MOVE;
    }
    
else if (name == "up")
    {
        
return UP;
    }

}


class WaitState;
class ReadyState;
class ActivatedState;
class MovingState;
class ZoomingState;

class Console;

class Element
{
public:
    Element( 
void ){}
    
explicit Element( std::string name ,Console * console):
                        _name(name),
                        _console(console)
    {
        line( 
"class Element");
        _stateid 
= READY;
        _stateSet 
= new StateSet();
        _touchNum 
= 0;
        print();
    }
    
virtual ~Element( void )
    {
        delete _stateSet;
        line( 
"class ~Element");
    }

    
void run(EventID e)
    {
        
switch (e)
        {
        
case DOWN:
            onTouchDown();
            
break;
        
case MOVE:
            onTouchMove();
            
break;
        
case UP:
            onTouchUp();
            
break;
        }
    }
    
void print( void )
    {
        std::cout 
<< "---  element  ---" << std::endl;
        std::cout 
<< _name << "" << getStateName(_stateid) << "" << _touchNum << std::endl;
        std::cout 
<< "-----------------" << std::endl;
        
return;
    }
    
    
void onTouchDown( void ) 
    {
        _stateSet
->getState(_stateid)->onTouchDown();
        _touchNum 
++;
    }
    
void onTouchMove( void )
    {
        _stateSet
->getState(_stateid)->onTouchMove();
    }
    
void onTouchUp( void )
    {
        _stateSet
->getState(_stateid)->onTouchUp();
        _touchNum 
--;
    }

    
void ready( void )
    {
        
return;
    }
    
void activate( void )
    {
        
return;
    }
    
void deactivate( void )
    {
        
return;
    }
    
void move( void )
    {
        
return;
    }
    
void moved( void )
    {
        
return;
    }
    
void zoom( void )
    {
        
return;
    }
    
void zoomed( void )
    {
        
return;
    }


public:
    std::
string        _name;
    StateID            _stateid;
    StateSet 
*        _stateSet;
    unsigned 
int    _touchNum;
    Console 
*        _console;
};



class WaitState: public State
{
public:
    WaitState( 
void ){ }
    
explicit WaitState( Element * element): _element(element){line("class Wait"); }
    
virtual ~WaitState(){line("class ~Wait "); }

    
virtual void onTouchDown( void )
    {
        _element
->ready();
        _element
->activate();
        _element
->_stateid = ACTIVATED;
        
return;
    }
    
virtual void onTouchMove( void ) 
    {
        
return;
    }
    
virtual void onTouchUp( void )
    {
        
return;
    }
protected:
    Element 
* _element;
};


class ReadyState: public State
{
public:
    ReadyState( 
void ){}
    
explicit ReadyState( Element * element): _element(element){line("class Ready"); }
    
virtual ~ReadyState( void ){line("class ~Ready"); }

    
virtual void onTouchDown( void )
    {
        _element
->activate();
        _element
->_stateid = ACTIVATED;
        
return;
    }
    
virtual void onTouchMove( void ) 
    {
        
return;
    }
    
virtual void onTouchUp( void )
    {
        
return;
    }
protected:
    Element 
* _element;
};

class ActivatedState: public State
{
public:
    ActivatedState( 
void ){}
    
explicit ActivatedState( Element * element): _element(element){line("class Activated"); }
    
virtual ~ActivatedState( void ){line("class ~Activated"); }

    
virtual void onTouchDown( void )
    {
        
return;
    }
    
virtual void onTouchMove( void ) 
    {
        
switch (_element->_touchNum )
        {
        
default:
        
case 2:
            _element
->zoom();
            _element
->_stateid = ZOOMING;
            
break;
        
case 1:
            _element
->move();
            _element
->_stateid = MOVING;
            
break;
        }
        
return;
    }
    
virtual void onTouchUp( void )
    {
        
return;
    }
protected:
    Element 
* _element;
};

class MovingState: public State
{
public:
    MovingState( 
void ){}
    
explicit MovingState( Element * element): _element(element){line("class Moving"); }
    
virtual ~MovingState( void ){line("class ~Moving"); }

    
virtual void onTouchDown( void )
    {
        _element
->_stateid = ACTIVATED;
        
return;
    }
    
virtual void onTouchMove( void ) 
    {
        _element
->move();
    }
    
virtual void onTouchUp( void )
    {
        _element
->moved();
        _element
->_stateid = ACTIVATED;
        
return;
    }
protected:
    Element 
* _element;
};


class ZoomingState: public State
{
public:
    ZoomingState( 
void ){}
    
explicit ZoomingState( Element * element): _element(element){line("class Zooming"); }
    
virtual ~ZoomingState( void ){line("class ~Zoom"); }

    
virtual void onTouchDown( void )
    {
        
return;
    }
    
virtual void onTouchMove( void ) 
    {
        _element
->zoom();
    }
    
virtual void onTouchUp( void )
    {
        
switch(_element->_touchNum)
        {
        
case 2:
            _element
->zoomed();
            _element
->_stateid = ACTIVATED;
            
break;
        }
        
return;
    }
protected:
    Element 
* _element;
};

class Console 
{
public:
    Console( 
void ){};
    
virtual ~Console( void )
    {
        
for(std::map<std::string, Element*>::iterator iter = _elementlist.begin();
            iter
!=_elementlist.end();iter++)
        {
            
if (iter->second != NULL)
            {
                delete iter
->second;
            }
        }
    }
    
    
void run(EventID e,std::string name)
    {

        std::map
<std::string, Element*>::iterator iter = _elementlist.find(name);
        
if (iter!= _elementlist.end())
        {
            iter
->second->run(e);
        }
    }

    
void createElement(std::string name)
    {
        Element 
* element = new Element(name,this);
        element
->_stateSet->setState(WAITE,new WaitState(element));
        element
->_stateSet->setState(READY,new ReadyState(element));
        element
->_stateSet->setState(ACTIVATED,new ActivatedState(element));
        element
->_stateSet->setState(MOVING,new MovingState(element));
        element
->_stateSet->setState(ZOOMING,new ZoomingState(element));
        _elementlist.insert(std::pair
<std::string,Element*>(name,element) );
    }

    
void eraseElement(std::string name)
    {
        std::map
<std::string, Element*>::iterator iter = _elementlist.find(name);
        
if (iter!= _elementlist.end())
        {
            delete iter
->second;
            _elementlist.erase(iter);
        }
    }

    
void printlist()
    {
        std::cout 
<< std::endl;
        std::cout 
<< " console element list" << std::endl;
        
for(std::map<std::string, Element*>::iterator iter = _elementlist.begin();
            iter
!=_elementlist.end();iter++)
        {
            iter
->second->print();
        }
        std::cout 
<< std::endl;
    }

    


public:
    std::map
<std::string, Element *>    _elementlist;

};

int main()
{    
    Console console;

    std::
string cmd;
    std::cout 
<< "now,you can create Element,input cmd[create]:";
    std::cin 
>> cmd;
    
while(1)
    {
        
if (cmd == "create")
        {
            std::cout 
<< "input element name:" ;
            std::cin 
>> cmd;
            
if (cmd!="")
            {
                console.createElement(cmd);
            }
        }
        
else if (cmd == "erase")
        {
            std::cout 
<< "input element name:";
            std::cin 
>> cmd;
            
if (cmd!="")
            {
                console.eraseElement(cmd);
            }
        }
        
else if (cmd == "down" || cmd == "move" || cmd == "up")
        {
            EventID e 
= getEventID(cmd);
            std::cout 
<< "input element name:";
            std::cin 
>> cmd;
            console.run(e,cmd);
        }
        console.printlist();
        std::cin 
>> cmd;
    }

    system(
"PAUSE");

    
return 0;
}