CSDN博客

img flashvan

Command模式实现的redo/undo功能(以前在闪吧发过)

发表于2004/9/21 13:13:00  2231人阅读

分类: 设计模式

记得对设计模式描述得最好的就是csdn上面的一篇《追mm和设计模式》的帖子
下面是其中对Command模式的描述:


Command—俺有一个mm家里管得特别严,没法见面,只好借助于她弟弟在我们俩之间
传送信息,她对我有什么指示,就写一张纸条让她弟弟带给我。这不,她弟弟又传送过来
一个command,为了感谢他,我请他吃了碗杂酱面,哪知道他说:“我同时给我姐姐三个
男朋友送command,就数你最小气,才请我吃面。”,

命令模式:命令模式把一个请求或者操作封装到一个对象中。命令模式把发出命令的责任
和执行命令的责任分割开,委派给不同的对象。命令模式允许请求的一方和发送的一方独
立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求是怎么被接收
,以及操作是否执行,何时被执行以及是怎么被执行的。系统支持命令的撤消。

这是Command模式的UML图 

 

 

class Command
{
        private function Command()
        {
        }
        // Methods
        public function Execute():Void
        {
        }
        public function UnExecute():Void
        {
        }
}

// "ConcreteCommand"
class CalculatorCommand extends Command
{
        // Fields
        private var $operator:String;
        private var operand:Number;
        private var calculator:Calculator;
        // Constructor
        public function CalculatorCommand(calculator:Calculator, $operator:String, operand:Number)
        {
                this.calculator = calculator;
                this.$operator = $operator;
                this.operand = operand;
        }
        // Properties
        public function set Operator(value:String):Void
        {
                $operator = value;
        }
        public function set Operand(value:Number):Void
        {
                operand = value;
        }
        // Methods
        public function Execute():Void
        {
                calculator.Operation($operator, operand);
        }
        public function UnExecute():Void
        {
                calculator.Operation(Undo($operator), operand);
        }
        // Private helper function
        private function Undo($operator:String):String
        {
                var undo:String ="";
                switch ($operator)
                {
                        case "+" :
                        undo = "-";
                        break;
                        case "-" :
                        undo = "+";
                        break;
                        case "*" :
                        undo = "/";
                        break;
                        case "/" :
                        undo = "*";
                        break;
                }
                return undo;
        }
}

// "Receiver"
class Calculator
{
        // Fields
        private var total:Number = 0;
        // Methods
        public function Operation($operator:String, operand:Number):Void
        {
                switch ($operator)
                {
                        case "+" :
                        total += operand;
                        break;
                        case "-" :
                        total -= operand;
                        break;
                        case "*" :
                        total *= operand;
                        break;
                        case "/" :
                        total /= operand;
                        break;
                }
                trace("Total =" + total + " (following" + $operator + " " + operand + ")");
        }
}

// "Invoker"
class User
{
        // Fields
        private var calculator:Calculator;
        private var commands:Array = new Array();
        private var current:Number = 0;
        public function User()
        {
                calculator = new Calculator();
        }
        // Methods
        public function Redo(levels:Number):Void
        {
                //trace(commands[current++] instanceof Command);
                trace("---- Redo " + levels + " levels ");
                // Perform redo operations
                for (var i = 0; i < levels; i++)
                {
                        if (current < commands.length - 1)
                        {
                                commands[current++].Execute();
                        }
                }
        }
        public function Undo(levels:Number):Void
        {
                trace("---- Undo" + levels + " levels ");
                // Perform undo operations
                for (var i = 0; i < levels; i++)
                {
                        if (current > 0)
                        {
                                commands[--current].UnExecute();
                        }
                }
        }
        public function Compute($operator:String, operand:Number):Void
        {
                // Create command operation and execute it
                var command:Command = new CalculatorCommand(calculator, $operator, operand);
                command.Execute();
                // Add command to undo list
                commands.push(command);
                current++;
        }
}

client.fla
// Create user and let her compute
var user:User = new User();
user.Compute('+', 100);
user.Compute('-', 50);
user.Compute('*', 10);
user.Compute('/', 2);
// Undo and then redo some commands
user.Undo(4);
user.Redo(3);

output:
Total =100 (following+ 100)
Total =50 (following- 50)
Total =500 (following* 10)
Total =250 (following/ 2)
---- Undo4 levels
Total =500 (following* 2)
Total =50 (following/ 10)
Total =100 (following+ 50)
Total =0 (following- 100)
---- Redo 3 levels
Total =100 (following+ 100)
Total =50 (following- 50)
Total =500 (following* 10)

0 0

相关博文

我的热门文章

img
取 消
img