设计模式学习总结7 - 行为型2 - Command命令模式
Command命令模式(行为型)
作用:
命令模式分离客户端的操作请求和请求的执行者。这种模式非常有用,它支持:
1、发送请求给多个接受着
2、排队、日志、拒绝请求
3、原始、简单的操作组合成高层事务
4、重做、撤销功能
Role
The Command pattern creates distance between the client that requests an operation and the object that can perform it. This pattern is particularly versatile. It cansupport:
• Sending requests to different receivers
• Queuing, logging, and rejecting requests
• Composing higher-level transactions from primitive operations
• Redo and Undo functionality
设计:
ICommand,执行操作的接口说明
Invoker,调用命令执行操作
Command,实现了操作的类,它通过调用接受者的操作来实现接口中说明的执行操作
Receiver,任意可执行请求活动的类
Action,需要被执行的操作
举例:
ICommand,菜单项
Command,剪切项
Receiver,执行剪切操作的接受者
Invoker,点击“剪切”菜单项
Action,执行“剪切”
实现:
示例1
{
public string strContent;
public Document()
{
strContent = "";
}
}
abstract class Command
{
public Command()
{ }
public abstract void Excute();
}
//写操作
class WriteCommand : Command
{
Document doc;
ArrayList ObjectState;
public WriteCommand(Document doc, ArrayList state)
{
this.doc = doc;
ObjectState = state;
}
public override void Excute()
{
doc.strContent += Console.ReadLine();
ObjectState.Add(doc.strContent);
}
}
//删除操作
class DeleteCommand : Command
{
Document doc;
ArrayList ObjectState;
public DeleteCommand(Document doc, ArrayList state)
{
this.doc = doc;
ObjectState = state;
}
public override void Excute()
{
doc.strContent = doc.strContent.Substring(0, doc.strContent.Length - 1);
ObjectState.Add(doc.strContent);
}
}
//撤销操作
class UnDoCommand : Command
{
Document doc;
ArrayList ObjectState;
public UnDoCommand(Document doc, ArrayList state)
{
this.doc = doc;
ObjectState = state;
}
public override void Excute()
{
doc.strContent = (string)ObjectState[ObjectState.Count - 2];
ObjectState.Add(doc.strContent);
}
}
class Program
{
static void Main(string[] args)
{
Document doc = new Document();
Console.WriteLine("Please Input next operation:");
string strOperation = Console.ReadLine();
Command com = null;
ArrayList ObjectState = new ArrayList();//Record state
while (strOperation != "Exit")
{
switch (strOperation.ToLower())
{
case "write":
com = new WriteCommand(doc, ObjectState);
com.Excute();
Console.WriteLine("Write Operation:" + doc.strContent);
break;
case "del":
com = new DeleteCommand(doc, ObjectState);
com.Excute();
Console.WriteLine("Delete Operation:" + doc.strContent);
break;
case "undo":
com = new UnDoCommand(doc, ObjectState);
com.Excute();
Console.WriteLine("UnDo Operation:" + doc.strContent);
break;
default:
Console.WriteLine("Wrong Operation:");
break;
}
Console.WriteLine("Please Input next operation:");
strOperation = Console.ReadLine();
}
}
}
运行结果:
Please Input next operation:
write
k
Write Operation:k
Please Input next operation:
write
i
Write Operation:ki
Please Input next operation:
write
d
Write Operation:kid
Please Input next operation:
write
d
Write Operation:kidd
Please Input next operation:
del
Delete Operation:kid
Please Input next operation:
undo
UnDo Operation:kidd
Please Input next operation:
示例2
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Command
{
class Program
{
delegate void Invoker();
static Invoker Execute, Undo, Redo;
class Command
{
public Command(Receiver receiver)
{
Execute = receiver.Action;
Redo = receiver.Action;
Undo = receiver.Reverse;
}
}
public class Receiver
{
string build, oldbuild;
string s = "some string ";
public void Action()
{
oldbuild = build;
build += s;
Console.WriteLine("Receiver is adding " + build);
}
public void Reverse()
{
build = oldbuild;
Console.WriteLine("Receiver is reverting to " + build);
}
}
static void Main(string[] args)
{
new Command (new Receiver());
Execute();
Redo();
Undo();
Execute();
Console.ReadLine();
}
}
}
应用场景:
命令可以由不同的方式由不同的接受者执行
简单的操作实现高层命令
在不同的时候指明,排队,执行命令
需要命令支持撤销功能
支持审计、所有命令执行日志记录
Use the Command pattern when…
You have:
• Commands that different receivers can handle in different ways
• A high-level set of commands that are implemented by primitive operations
You want to:
• Specify, queue, and execute commands at different times
• Support an Undo function for commands
• Support auditing and logging of all changes via commands
总结:
Command命令模式是一种行为型模式,它主要解决的问题是:在软件构建过程中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”的问题。GoF《设计模式》中说道:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
Command模式的几个要点:
1、 Command模式的根本目的在于将“行为请求者”与“行为实现者”解耦,在面向对象语言中,常见的实现手段是“将行为抽象为对象”。
2、 实现ICommand接口的具体命令对象Command 有时候根据需要可能会保存一些额外的状态信息。
3、 Command模式与C#中的Delegate有些类似。但两者定义行为接口的规范有所区别:Command以面向对象中的“接口-实现”类定义行为接口规范,更严格,更符合抽象原则:Delegate以函数签名来定义行为接口规范,更灵活,但抽象能力比较弱
实现Command模式需要考虑的一些问题:
1、 支持取消和重做:为了达到这个目的Command类中要存储额外的状态信息。也就是上图中Command的state属性。
2、 避免取消操作中过程中的错误积累:由于命令重复的执行、取消执行和重执行的过程可能会积累错误,以致一个应用的状态最终偏离初始值。这就有必要在Command中存入更多的信息以保证这些对象可被精确的复原。
posted on 2010-03-04 16:14 Utopia Coming 阅读(1178) 评论(1) 编辑 收藏 举报