设计模式(C++实现)(二十)——命令模式

示例问题:

在软件开发这个行业,有一个重要的职位——项目经理,这个人对内负责项目及项目团队的管理,对外负责和产品经理、领导等的沟通。项目经理对外沟通获得所有的需求,记录需求内容,撤销需求(当产品经理或者领导觉得某条需求不妥时),当需求整理到可以做产品的时候,会将任务分配给程序员去开发。编程描述上面问题。

分析:

如果没有项目经理这个职位,让程序员直接和产品经理、领导沟通,并负责项目的管理,可想而知程序员的工作会多么的繁杂,多么容易出错。项目经理在这个示例问题的作用,就是命令模式的核心——“管理并发号命令”。

解决方案:

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++实现)(总)

上一篇:设计模式(C++实现)(十九)——访问者模式

下一篇:设计模式(C++实现)(二十一)——职责链模式

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值