模式六:命令模式(Command Pattern)——封装请求对象

命令模式

将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。

应用分析

命令模式的设计,定义公共的Command接口,使请求调用者和请求接收者之间解耦,便于请求扩展。

Command:定义命令的统一接口
ConcreteCommand:Command接口的实现者,用来执行具体的命令,某些情况下可以直接用来充当Receiver。
Receiver:命令的实际执行者
Invoker:命令的请求者,是命令模式中最重要的角色。这个角色用来对各个命令进行控制。

实例分析

用一个遥控器控制不同电器,执行不同操作,比如:灯的开关、电视机的开关等,这样,我们可以将最终的接收者灯和电视的行为封装成命令对象,通过命令对象的统一接口execute执行相关操作。

代码分析

//Command.h
//Command接口
#ifndef COMMAND_H
#define COMMAND_H

#include <iostream>

class Command
{
public:
	virtual void execute()=0;
	virtual void undo()=0;
	virtual ~Command(){}
};

class NoCommand:public Command
{
public:
	void execute()
	{
		std::cout<<"Nothing on"<<std::endl;
	}
	void undo()
	{
		std::cout<<"Nothing off"<<std::endl;
	}
};
#endif


//Receiver.h
//接收者
#ifndef RECEIVER_H
#define RECEIVER_H

#include <iostream>

class Light
{
public:
	void on()
	{
		std::cout<<"Light on"<<std::endl;
	}
	void off()
	{
		std::cout<<"Light off"<<std::endl;
	}
};

class TV
{
public:
	void on()
	{
		std::cout<<"TV on"<<std::endl;
	}
	void off()
	{
		std::cout<<"TV off"<<std::endl;
	}
};

#endif


//ConcreteCommand.h
//命令实体对象
#ifndef COMCRETECOMMAND_H
#define COMCRETECOMMAND_H

#include "Command.h"
#include "Receiver.h"

class OnTVCommand:public Command
{
private:
	TV &TVReceive;
public:
	OnTVCommand(TV & TVre):TVReceive(TVre){}
	void execute()
	{
		TVReceive.on();
	}
	void undo()
	{
		TVReceive.off();
	}
};

class OffTVCommand:public Command
{
private:
	TV &TVReceive;
public:
	OffTVCommand(TV & TVre):TVReceive(TVre){}
	void execute()
	{
		TVReceive.off();
	}
	void undo()
	{
		TVReceive.on();
	}
};

class OnLightCommand:public Command
{
private:
	Light &LightReceiver;
public:
	OnLightCommand(Light &LightRe):LightReceiver(LightRe){}
	void execute()
	{
		LightReceiver.on();
	}
	void undo()
	{
		LightReceiver.off();
	}
};

class OffLightCommand:public Command
{
private:
	Light &LightReceiver;
public:
	OffLightCommand(Light &LightRe):LightReceiver(LightRe){}
	void execute()
	{
		LightReceiver.off();
	}
	void undo()
	{
		LightReceiver.on();
	}
};

#endif


//Invoker.h
//调用者
#ifndef INVOKER_H
#define INVOKER_H

#include "Command.h"

class Command;
NoCommand noCommand;

class Invoker
{
private:
	Command * undoCommand;
	Command * onCommands[7];
	Command * offCommands[7];
public:
	Invoker()
	{
		for(int i=0;i<7;++i)
		{
			onCommands[i]=&noCommand;
			offCommands[i]=&noCommand;
		}
		undoCommand=&noCommand;
	}
	void setCommand(int slot,Command & onCommand,Command & offCommand)
	{
		onCommands[slot]=&onCommand;
		offCommands[slot]=&offCommand;
	}
	void onButton(int slot)
	{
		onCommands[slot]->execute();
		undoCommand=onCommands[slot];
	}
	void offButton(int slot)
	{
		offCommands[slot]->execute();
		undoCommand=offCommands[slot];
	}
	void undo()
	{
		undoCommand->undo();
	}
};

#endif



//Main.cpp
//测试程序
#include "ConcreteCommand.h"
#include "Invoker.h"

int main()
{
	TV tv;
	Light light;

	OnTVCommand ontvCommand(tv);
	OffTVCommand offtvCommand(tv);
	OnLightCommand onlightCommand(light);
	OffLightCommand offlightCommand(light);

	Invoker invoker;
	invoker.setCommand(0,ontvCommand,offtvCommand);
	invoker.setCommand(1,onlightCommand,offlightCommand);

	invoker.onButton(0);
	invoker.offButton(1);
	invoker.onButton(3);
	invoker.onButton(1);
	invoker.undo();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值