您的位置:首页 > 其它

使用Command模式实现撤销机制 (Code Project 精选翻译)

2005-06-08 17:01 459 查看
使用Command模式实现撤销机制[1]

Written by Matt Berther

Translated by Allen Lee[2]

Reviewed by Teddy Tam & Allen Lee

Introduction

Command是一个非常强大的设计模式,它的作用是将一个请求封装成一个对象,从而使你能够把来自客户端的不同请求(request)、队列(queue)或者日志记录请求(log request)包装成参数,并且还支持可撤销操作。

这个模式的一个最大的优点就是,它能够把执行某操作的对象和实际知道如何处理该操作的对象之间的耦合度降低。

今天,我要向大家介绍如何使用这个Command模式来实现撤销功能。至于我们的例子,我们将会开发一个非常简单的类记事本(Notepad clone)。你无须大惊小怪,因为这(个记事本)已经能够展现出这个模式的威力了。

The Code

我们要做的第一件事就是创建一个用于包装TextBox控件的抽象层(abstraction)。在Command模式里,这个抽象层被称为接收者(Reciever)。在我们的例子里面,这个接收者是一个叫做Document的对象。

class Document
public abstract class Command

public abstract class UndoableCommand : Command
class BoldCommand : UndoableCommand
class CommandManager
public class MainForm : System.Windows.Forms.Form
private System.Windows.Forms.TextBox documentTextbox;

private CommandManager commandManager = new CommandManager();

private Document document;

public MainForm()
//
// Required for Windows Form Designer support
//
InitializeComponent();

document = new Document(this.documentTextbox);
}

// a bunch of snipped code

private void cutMenuItem_Click(object sender, System.EventArgs e)
commandManager.ExecuteCommand(new CutCommand(document));
}

private void pasteMenuItem_Click(object sender, System.EventArgs e)
commandManager.ExecuteCommand(new PasteCommand(document));
}

// etc}
我写了一个完整的示范程序并提供了下载。请注意,在这里,这个文本编辑器是尚未完善的初级品。而你的任务,如果你愿意接受的话,为这个程序加入重做(redo)的功能[4]。

希望我已阐明此模式之威力及如何轻松使用其来添加合成功能。现在添加新的命令非常容易了,因为你不再需要触及任何现有的代码。

Comments by Allen Lee

[1] 版权问题:文章版权归原作者所有,此译文版仅供学习和研究之用。有关作者的资料以及完整的源代码请跳到Using the Command pattern for undo functionality(原文)。
[2] 翻译工作:本文首先由我完成翻译初稿,并在需要讨论的翻译点进行注释;然后提交给Teddy进行第一次审校;接着由我和Teddy共同就相关需要斟酌和修正的翻译点进行讨论,并有Teddy浏览全文一次完成第二次审校;最后由我进行后期工作(包括排版)时再通读全文完成最终稿。在此期间,非常感谢Teddy对本文审校工作的大力支持。他不但对本文进行基本审校,而且还用他老练的英语翻译功底为本文多处地方润色。
[3] 此处原句为:Secondly, we will need to design our Command interfaces. 这里的interface是有别于C#的关键字(keyword)interface的。

前者指的是对象对外公开发布(publish)的一个或多个成员;而后者却相当于一张完整的契约,契约里面会明确规定遵守契约的对象必须实现的一个或多个成员。
用一个更加接近现实的例子——三脚插座,每一个插孔都是一个独立的对外(公开发布)的接口,此为前者之概念;而每一个三角插座,必须遵守以下约定:提供三个插孔,分别用于接火线、接零线和接地,此为后者之概念。
换一句话,前者之概念可以是后者之概念的一个或多个成员。不过这里还是统一翻译成接口,希望不会造成不必要的误解。
“救命啊!好好的一篇文章,你为什么...?“我无意在这里分解概念来增加大家的思想负担,如果你看到这里,打从心底冒出一句类似的话,那么,我建议你无视本注释的存在,只要你能够从文章中学到应该学到的东西(该是什么呢?)!

[4] 最后,原文作者向你们布置了家庭作业,就是动手实现一个重做的功能,完善那个未完善的初级品。再好的理论、再有吸引力的文章,如果没有实践,那只能是一场空谈,也是在浪费时间!So go practising!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: