命令模式
定义:
将“请求”封装成对象,将请求的发送者和接受者解耦,但不关心请求将以何种方式呗处理。
适用性:
命令模式经常与职责链模式和组合模式一起使用。职责链模式处理命令模式封装的对象,组合模式可以把简单的命令对象组合成复杂的命令对象。
实现:
1、建立命令队列
2、可以将命令计入日志
3、接收请求的一方可以拒绝
4、添加一个新命令不影响其他类
//使用命令模式实现一个命令行计算器,并支持undo和redo.
#include <stdio.h>
#include <stdlib.h>
#include <string>
using namespace std;
//简单的计算器
class Calculator
{
public:
Calculator(){}
virtual ~Calculator(){}
float add(float a, float b)
{
return a+b;
}
float sub(float a, float b)
{
return a-b;
}
float mul(float a, float b)
{
return a*b;
}
float div(float a, float b)
{
if(b == 0)
{
return 0;
}
return a/b;
}
};
//命令类
class Commend
{
public:
Commend(Calculator *cal)
{
this->m_cal = cal;
}
virtual ~Commend(){}
virtual void excute(float a, float b)=0 ;
virtual void undo()=0;
virtual void redo()=0;
Calculator *m_cal;
float m_result;
float m_preResult;
};
//加法命令
class AddCommend:public Commend
{
public:
AddCommend(Calculator *cal):Commend(cal){}
virtual ~AddCommend(){}
//执行操作
void excute(float a, float b)
{
this->m_result = this->m_cal->add(a,b);
this->m_preResult = this->m_result;
printf("add result %f\n",this->m_result);
}
//撤销操作
void undo()
{
this->m_result = 0;
printf("add result is undo\n");
}
//恢复命令
void redo()
{
this->m_result = this->m_preResult;
printf("add redo result %f\n",this->m_result);
}
};
//减法命令
class SubCommend:public Commend
{
public:
SubCommend(Calculator *cal):Commend(cal){}
virtual ~SubCommend(){}
//执行操作
void excute(float a, float b)
{
this->m_result = this->m_cal->sub(a,b);
this->m_preResult = this->m_result;
printf("sub result %f\n",this->m_result);
}
//撤销操作
void undo()
{
this->m_result = 0;
printf("sub result is undo\n");
}
//恢复命令
void redo()
{
this->m_result = this->m_preResult;
printf("sub redo result %f\n",this->m_result);
}
};
//乘法命令
class MulCommend:public Commend
{
public:
MulCommend(Calculator *cal):Commend(cal){}
virtual ~MulCommend(){}
//执行操作
void excute(float a, float b)
{
this->m_result = this->m_cal->mul(a,b);
this->m_preResult = this->m_result;
printf("mul result %f\n",this->m_result);
}
//撤销操作
void undo()
{
this->m_result = 0;
printf("mul result is undo\n");
}
//恢复命令
void redo()
{
this->m_result = this->m_preResult;
printf("mul redo result %f\n",this->m_result);
}
};
//除法命令
class DivCommend:public Commend
{
public:
DivCommend(Calculator *cal):Commend(cal){}
virtual ~DivCommend(){}
//执行操作
void excute(float a, float b)
{
this->m_result = this->m_cal->div(a,b);
this->m_preResult = this->m_result;
printf("div result %f\n",this->m_result);
}
//撤销操作
void undo()
{
this->m_result = 0;
printf("div result is undo\n");
}
//恢复命令
void redo()
{
this->m_result = this->m_preResult;
printf("div redo result %f\n",this->m_result);
}
};
class DoCalculate
{
public:
DoCalculate(){}
virtual ~DoCalculate(){}
void setCommend(Commend *com)
{
this->m_com = com;
}
void calculate(float a, float b)
{
this->m_com->excute(a,b);
}
void undo()
{
this->m_com->undo();
}
void redo()
{
this->m_com->redo();
}
Commend *m_com;
};
int main(int argc,char** argv)
{
Calculator cal;
DoCalculate doc;
AddCommend add(&cal);
SubCommend sub(&cal);
MulCommend mul(&cal);
DivCommend div(&cal);
float a,b;
char op;
while(scanf("%f %c %f",&a,&op,&b))
{
printf("tzz %f %c %f\n",a,op,b);
switch(op) //argv 的格式为 A op B
{
case '+':
{
doc.setCommend(&add);
doc.calculate(a,b);
}
break;
case '-':
{
doc.setCommend(&sub);
doc.calculate(a,b);
}
break;
case '*':
{
doc.setCommend(&mul);
doc.calculate(a,b);
}
break;
case '/':
{
doc.setCommend(&div);
doc.calculate(a,b);
}
break;
case 'u'://撤销
doc.undo();
break;
case 'r'://redo
doc.redo();
break;
}
}
return 0;
}