示例问题:
在软件开发这个行业,有一个重要的职位——项目经理,这个人对内负责项目及项目团队的管理,对外负责和产品经理、领导等的沟通。项目经理对外沟通获得所有的需求,记录需求内容,撤销需求(当产品经理或者领导觉得某条需求不妥时),当需求整理到可以做产品的时候,会将任务分配给程序员去开发。编程描述上面问题。
分析:
如果没有项目经理这个职位,让程序员直接和产品经理、领导沟通,并负责项目的管理,可想而知程序员的工作会多么的繁杂,多么容易出错。项目经理在这个示例问题的作用,就是命令模式的核心——“管理并发号命令”。
解决方案:
Command.h
在该文件中,实现了程序员类,命令基类ICommand,及其子类CDevWebCommand(开发web端的命令)、CModServerCommand(修改服务端的命令)、CDevPCCommand(开发PC端的命令)、CDevAndroidCommand(开发Androidy客户端的命令)、CDeviOSCommand(开发iOS客户端的命令),还有项目经理类CProjectManager。
项目经理类,能够记录日志,加入命令,删除命令,并负责命令的统一执行。
#pragma once
#include <iostream>
#include <string>
#include <map>
//程序员
class CProgrammer
{
public:
CProgrammer()
{
}
virtual ~CProgrammer()
{
}
void DevelopWeb()
{
std::cout << "开发Web端" << std::endl;
}
void ModServer()
{
std::cout << "修改服务端" << std::endl;
}
void DevelopPC()
{
std::cout << "开发PC端" << std::endl;
}
void DevelopAndroid()
{
std::cout << "开发Android客户端" << std::endl;
}
void DevelopiOS()
{
std::cout << "开发iOS客户端" << std::endl;
}
};
//命令基类
class ICommand
{
public:
ICommand(CProgrammer* pProgrammer)
:m_pProgrammer(pProgrammer)
{
}
virtual ~ICommand()
{
}
virtual void ExecuteCommand() = 0;
CProgrammer* m_pProgrammer;
};
//开发web端的命令
class CDevWebCommand : public ICommand
{
public:
CDevWebCommand(CProgrammer* pProgrammer) : ICommand(pProgrammer)
{
}
virtual ~CDevWebCommand()
{
}
void ExecuteCommand()
{
if (nullptr != m_pProgrammer)
{
m_pProgrammer->DevelopWeb();
}
}
};
//修改服务端的命令
class CModServerCommand : public ICommand
{
public:
CModServerCommand(CProgrammer* pProgrammer) : ICommand(pProgrammer)
{
}
virtual ~CModServerCommand()
{
}
void ExecuteCommand()
{
if (nullptr != m_pProgrammer)
{
m_pProgrammer->ModServer();
}
}
};
//开发PC端的命令
class CDevPCCommand : public ICommand
{
public:
CDevPCCommand(CProgrammer* pProgrammer) : ICommand(pProgrammer)
{
}
virtual ~CDevPCCommand()
{
}
void ExecuteCommand()
{
if (nullptr != m_pProgrammer)
{
m_pProgrammer->DevelopPC();
}
}
};
//开发Androidy客户端的命令
class CDevAndroidCommand : public ICommand
{
public:
CDevAndroidCommand(CProgrammer* pProgrammer) : ICommand(pProgrammer)
{
}
virtual ~CDevAndroidCommand()
{
}
void ExecuteCommand()
{
if (nullptr != m_pProgrammer)
{
m_pProgrammer->DevelopAndroid();
}
}
};
//开发iOS客户端的命令
class CDeviOSCommand : public ICommand
{
public:
CDeviOSCommand(CProgrammer* pProgrammer) : ICommand(pProgrammer)
{
}
virtual ~CDeviOSCommand()
{
}
void ExecuteCommand()
{
if (nullptr != m_pProgrammer)
{
m_pProgrammer->DevelopiOS();
}
}
};
//项目经理
class CProjectManager
{
public:
CProjectManager()
{
}
virtual ~ CProjectManager()
{
}
void SetOrder(std::string strCommandName, ICommand* pCommand)
{
std::cout << "记录日志 : " << strCommandName << std::endl;
m_mapCommand[strCommandName] = pCommand;
}
void RemoveOrder(std::string strCommandName)
{
std::cout << "记录日志 : 删除" << strCommandName << std::endl;
std::map<std::string, ICommand*>::iterator itor = m_mapCommand.find(strCommandName);
if (itor != m_mapCommand.end())
{
m_mapCommand.erase(itor);
}
}
void Execute()
{
for (auto itor : m_mapCommand)
{
if (nullptr != itor.second)
{
itor.second->ExecuteCommand();
}
}
}
private:
std::map<std::string, ICommand*> m_mapCommand;
};
main.cpp
// main.cpp : Defines the entry point for the console application.
//
#include "Command.h"
int main()
{
CProgrammer Programmer;
CDevWebCommand* pDevWebCommand = new(std::nothrow)CDevWebCommand(&Programmer);
CModServerCommand* pModServerCommand = new(std::nothrow)CModServerCommand(&Programmer);
CDevPCCommand* pDevPCCommand = new(std::nothrow)CDevPCCommand(&Programmer);
CDevAndroidCommand* pDevAndroidCommand = new(std::nothrow)CDevAndroidCommand(&Programmer);
CDeviOSCommand* pDeviOSCommand = new(std::nothrow)CDeviOSCommand(&Programmer);
CProjectManager ProjectManager;
ProjectManager.SetOrder("开发Web端", pDevWebCommand);
ProjectManager.SetOrder("修改服务端", pModServerCommand);
ProjectManager.SetOrder("开发PC端", pDevPCCommand);
ProjectManager.SetOrder("开发Android端", pDevAndroidCommand);
ProjectManager.SetOrder("开发iOS端", pDeviOSCommand);
ProjectManager.RemoveOrder("开发Android端");
ProjectManager.Execute();
system("pause");
return 0;
}
运行结果
命令模式的使用:
命令模式:将一个请求封装成一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
命令模式的优点:
1. 能较容易地设计一个命令队列;
2. 在需要的情况下,可以较容易地将命令记入日志;
3. 允许接收请求的一方决定是否要否决请求;
4. 可以容易地实现对请求的撤销和重做;
5. 由于加入新的具体命令类不影响其他的类,因此增加新的具体命令类很容易;
6. 把请求一个操作的对象与知道怎么执行一个操作的对象分割开。
何时使用命令模式:
对请求排队或记录请求日志,以及支持可撤销的操作,“行为请求者”与“行为实现者”的紧耦合不太合适时
返回目录:设计模式(C++实现)(总)