初尝Command 模式
在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。但在某些场合,比如要对行为进行“记录、撤销/重做、事务”等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将“行为请求者”与“行为实现者”解耦?将一组行为抽象为对象,可以实现二者之间的松耦合。这就是本文要说的Command模式。
意图
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。
结构图
代码:
using System;
using System.Collections.Generic;
namespace Command
{
class Program
{
static void Main(string[] args)
{
//只有计算能力
Caculator c = new Caculator();
//实现Undo
CaculatorCommand cc = new CaculatorCommand(c);
//添加了Undo的堆栈
CaculatorInvoker cInvoker = new CaculatorInvoker(cc);
cInvoker.Caculate('+',2);
cInvoker.Caculate('*', 7);
cInvoker.Caculate('-', 3);
cInvoker.Caculate('/', 4);
cInvoker.UnCaculate();
cInvoker.UnCaculate();
cInvoker.UnCaculate();
}
}
interface Command {
void SetParam(object[] objects);
void Excute();
void UnExcute();
}
class Caculator {
private double total = 0;
public void Compute(char @operator,double param) {
switch (@operator) {
case '+': total += param; break;
case '-': total -= param; break;
case '*': total *= param; break;
case '/': total /= param; break;
default: throw new ArgumentException();
}
Console.WriteLine("Current value = {0,3} (following {1} {2})",total,@operator,param);
}
}
class CaculatorCommand : Command {
private Caculator caculator;
private char @operator;
private double param;
public CaculatorCommand(Caculator c) {
this.caculator = c;
}
public void SetParam(object[] objects) {
this.@operator = (char)objects[0];
this.param = (double)objects[1];
}
public void Excute() {
caculator.Compute(@operator,param);
}
public void UnExcute() {
caculator.Compute(this.Undo(@operator),param);
}
private char Undo(char @op) {
switch (@op) {
case '+': return '-';
case '-': return '+';
case '*': return '/';
case '/':return '*';
default: throw new ArgumentException();
}
}
}
class CaculatorInvoker {
private Command cmd;
private Stack
运行截图:
话说回来,如果只看Main 函数,感觉像用的是Decorator 模式。从这一点不难发现,模式之间由于总体原则的类似,导致他们长得都很相像。


近期评论