作用及特点:”行为请求者“与”行为实现者“通常呈现一种”紧耦合“。
但在某些场合——比如需要对行为进行”记录、撤销、事务“等处理,这种无法抵御变化的紧耦合是不合适的。
Command模式的根本目的在于将”行为请求者“与”行为实现者“解耦,在面向对象语言中,常见的实现手段是”将行为抽象为对象“。
因为命令需要有接收者,命令类和接收者类是关联关系,所以具体命令类在创建的时候,记录一下接收者的指针。
命令类是有统一的执行接口,它为纯虚函数,具体的命令类可以对执行接口进行重写。
命令类和管理员类为聚合关系。
现在马戏团管理员要让动物们表演节目了,马戏团管理员要有一个命令列表,这些命令可以让动物们表演节目,命令是要有接受者的,第一个命令的接收者是老鹰,老鹰的节目是飞翔。
第二个命令的接收者是老虎,老虎的节目是奔跑。
class ICommond
{
public:
virtual void execute() = 0;
};
class TigerCommond :public ICommond
{
public:
TigerCommond(Tiger* animal);
virtual void execute();
private:
Animal* m_animal = nullptr;
};
class EagleCommond :public ICommond
{
public:
EagleCommond(Eagle* animal);
virtual void execute();
private:
Animal* m_animal = nullptr;
};
animal.cpp代码实现---- 命令类
TigerCommond::TigerCommond(Tiger* animal):m_animal(animal)
{
}
void TigerCommond::execute()
{
static_cast<Tiger*>(m_animal)->running();
}
EagleCommond::EagleCommond(Eagle* animal) :m_animal(animal)
{
}
void EagleCommond::execute()
{
static_cast<Eagle*>(m_animal)->flying();
}
AnimalManager.h代码实现----管理者类
class AnimalManager
{
public:
void addCommond(ICommond* commond); //增加命令
void callCommond(); //执行表演命令
private:
std::list<ICommond*> m_commond;
};
AnimalManager.cpp代码实现----管理者类
void AnimalManager::addCommond(ICommond* commond)
{
auto iter = std::find(m_commond.begin(), m_commond.end(), commond);
if (iter == m_commond.end())
{
m_commond.push_back(commond);
}
}
void AnimalManager::callCommond()
{
for (auto iter : m_commond)
{
iter->execute();
}
}
输出结果和总结
- 命令类中要有接收者,可以在具体命令初始化的时候传进去,记录接收者的指针;
- 管理类要有存储具体命令实例的容器,可增删改容器中的命令。
int main()
{
AnimalFood animalFood;
Tiger* tiger = new Tiger("小脑斧", &animalFood);
Eagle* eagle = new Eagle("大佬凝", &animalFood);
printf("----------------------------------\n\n");
TigerCommond* tigerCommond = new TigerCommond(tiger);
EagleCommond* eagleCommond = new EagleCommond(eagle);
GetAnimalManager()->addCommond(tigerCommond);
GetAnimalManager()->addCommond(eagleCommond);
GetAnimalManager()->callCommond();
}
结果
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)