(二)问题的分析、模式的选择
在上一篇文章的结束,我提到我的解决方法。因此在这篇文章中,我得分析我的理由。
其实大家都使用过移动的10086流程。流程的每个分支也可以定义一个状态,也可以定义一个动作。我们抛开概念的差异性,来分析10086流程。
以下是10086的部分流程图:
流程的当前行为都基于当前的状态MEMENTO,根据当前的MEMENTO改变程序的行为。因此这是采用STATE模式的原因,但是为什么要采用COMPOSITE?
在分析这个问题之前,我先绕一个弯。很多人都应该玩过网络游戏,在网络游戏中,我们经常采用连击,或者是自己组合武功招式。我在玩游戏的过程中,一直在思考程序是怎么解决连击、组合武功的方案。
在学习设计模式之后,我自己想了一个解决方案:
在程序设计过程,使用COMPOSITE模式,将武功分解成一些最基本的元操作。然后再利用这些操作组成连击。
在设计过程中,我们将最基本的操作定义成一个Leaf,然后一个连击就是一个Composite。
为了支持用户自己编辑武功,我们无法知道用户怎么编辑武功,所以我们无法预定义适合Composite,因此我们必须定义一个Composite,一个让用户增加、删除招式的接口。
以下是简要的模式图:
以下附上简要的实现代码(欢迎大家提出修改的意见)
class Act
...{
public:
Act();
virtual ~Act();
void Operation();
void AddAct(Act* act);
Act* GetAct(unsigned int idx);
};
class BaseAct1:public Act
...{
public:
BaseAct1();
virtual ~BaseAct1();
void Operation()...{...}
void AddAct(Act* act)...{;}
Act* GetAct(unsigned int idx)...{return NULL}
};
class BaseAct2:public Act
...{
public:
BaseAct2();
virtual ~BaseAct2();
void Operation()...{...}
void AddAct(Act* act)...{;}
Act* GetAct(unsigned int idx)...{return NULL}
};
class BaseAct3:public Act
...{
public:
BaseAct3();
virtual ~BaseAct3();
void Operation()...{...}
void AddAct(Act* act)...{;}
Act* GetAct(unsigned int idx)...{return NULL}
};
class BaseAct4:public Act
...{
public:
BaseAct4();
virtual ~BaseAct4();
void Operation()...{...}
void AddAct(Act* act)...{;}
Act* GetAct(unsigned int idx)...{return NULL}
};
class CompositeAct:public Act
...{
public:
class F
...{
public:
void operator()(Act* act)...{if(act != NULL) act->Operation();}
};
CompositeAct();
virtual ~CompositeAct();
void Operation()...{std::for_each(_actVec.begin(),_actVec.end(),F());}
void AddAct(Act* act)...{_actVec.push_back(act);}
Act* GetAct(unsigned int idx)...{return (idx < _actVec.size())? _actVec[idx]:NULL;}
private:
std::vector<Act*> _actVec;
};
class BaseActMannager
...{
public:
class F
...{
public:
void operator()(Act* act)...{delete act;}
}
Act* findAct(int key)
...{
std::map<int,Act*>::iterator it = _actMap.find(key);
if(it != _actMap.end())
return it->second;
return NULL;
}
~BaseActMannager()...{std::for_each(_actVec.begin(),_actVec.end(),F());}
static BaseActMannager* instance()
...{
if(_mgr == NULL)
_mgr = new BaseActMannager();
return _mgr;
}
private:
BaseActMannager()
...{
_actMap.insert(std::make_pair(1,new BaseAct1));
_actMap.insert(std::make_pair(2,new BaseAct2));
_actMap.insert(std::make_pair(3,new BaseAct3));
_actMap.insert(std::make_pair(4,new BaseAct4));
};
BaseActMannager(const BaseActMannager&);
std::map<int,Act*> _actMap;
static BaseActMannager* _mgr;
};
BaseActMannager* BaseActMannager::_mgr = NULL;
class Pepole
...{
public:
Act();
virtual ~Act();
void Operation();
void AddAct(Act* act);
Act* GetAct(unsigned int idx);
};
class BaseAct1:public Act
...{
public:
BaseAct1();
virtual ~BaseAct1();
void Operation()...{...}
void AddAct(Act* act)...{;}
Act* GetAct(unsigned int idx)...{return NULL}
};
class BaseAct2:public Act
...{
public:
BaseAct2();
virtual ~BaseAct2();
void Operation()...{...}
void AddAct(Act* act)...{;}
Act* GetAct(unsigned int idx)...{return NULL}
};
class BaseAct3:public Act
...{
public:
BaseAct3();
virtual ~BaseAct3();
void Operation()...{...}
void AddAct(Act* act)...{;}
Act* GetAct(unsigned int idx)...{return NULL}
};
class BaseAct4:public Act
...{
public:
BaseAct4();
virtual ~BaseAct4();
void Operation()...{...}
void AddAct(Act* act)...{;}
Act* GetAct(unsigned int idx)...{return NULL}
};
class CompositeAct:public Act
...{
public:
class F
...{
public:
void operator()(Act* act)...{if(act != NULL) act->Operation();}
};
CompositeAct();
virtual ~CompositeAct();
void Operation()...{std::for_each(_actVec.begin(),_actVec.end(),F());}
void AddAct(Act* act)...{_actVec.push_back(act);}
Act* GetAct(unsigned int idx)...{return (idx < _actVec.size())? _actVec[idx]:NULL;}
private:
std::vector<Act*> _actVec;
};
class BaseActMannager
...{
public:
class F
...{
public:
void operator()(Act* act)...{delete act;}
}
Act* findAct(int key)
...{
std::map<int,Act*>::iterator it = _actMap.find(key);
if(it != _actMap.end())
return it->second;
return NULL;
}
~BaseActMannager()...{std::for_each(_actVec.begin(),_actVec.end(),F());}
static BaseActMannager* instance()
...{
if(_mgr == NULL)
_mgr = new BaseActMannager();
return _mgr;
}
private:
BaseActMannager()
...{
_actMap.insert(std::make_pair(1,new BaseAct1));
_actMap.insert(std::make_pair(2,new BaseAct2));
_actMap.insert(std::make_pair(3,new BaseAct3));
_actMap.insert(std::make_pair(4,new BaseAct4));
};
BaseActMannager(const BaseActMannager&);
std::map<int,Act*> _actMap;
static BaseActMannager* _mgr;
};
BaseActMannager* BaseActMannager::_mgr = NULL;
class Pepole