命令模式再学习
来源:互联网 发布:js实现日期选择 编辑:程序博客网 时间:2024/06/05 20:50
以前也写过设计模式,总是罗列一些自己都看不懂的话。一直都认为要想对设计模式有很好的理解,离不了实践的经验和不断的学习总结。这次是结合自己的理解并且本着通俗易懂的原则来写,适合入门级学习的人。
有这么一种情况:在vs中。新建一个cs项目,按下F5运行,出现了一个窗体;又新建了一个bs项目,同样按下F5,这时运行时出现的是浏览器的页面。问题来了,在不同的应用环境下,按下同一个按钮,却出现了不同的运行结果。如果你是开发人员,你会如何实现?
最糟糕的设计也不过是每一个动作都重新实现一遍,但是你想一想,vs中有多少这样的功能,如果要是一个一个的实现,那多麻烦,维护起来更是可怕。针对于这样的一种情况,可以使用命令模式。我们都知道所有的设计模式无非就是为了解耦,命令模式是怎么解耦的?适合在哪些情况下使用?
命令模式的核心在于将动作的请求者从动作的执行者中解耦。先看一张类图:
这是《大话设计模式》中讲烤羊肉串的例子的类图。就以它来讲:以前是客户端和烤肉串者紧密耦合,为了解耦在两者之间加入了”第三者”---服务员类和命令类。客户端持有服务员的引用,通过设置命令方法发出请求。通过通知执行方法告诉命令类去执行。而命令类和烤肉串类对动作的执行进行了封装,通过服务员传入不同参数,决定具体使用哪个命令,然后直接执行命令。这样就实现了动作的请求和动作的执行的分离。
这样解耦后有什么好处?
1. 如果另外需要几串烤牛板筋的话,就不需要修改类,直接在添加烤牛板筋类来继承命令类。(开闭原则:对扩展是开放的,对修改是关闭)
2. 另外一个重要的点在服务员类上。设置命令。可以较容易地设计一个命令队列,在需要的情况下,可以将命令记入日志。要怎么做?当我们执行命令的时候,将历史记录存储在磁盘上,一但系统死机,就可以将命令对象重新加载,并依次调用这些对象的execute方法。
3. 可以容易地实现redo 和 undo 操作。
应用命令模式的具体实例实现redo 和 undo 操作。C#的控制台程序模拟:
Calculator相当于烤肉串者
/* *创建人:王雅瑾 *创建日期:2014/7/31 11:01:43 *说明: *版权所有: */using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Calculator{ class Calculator { private int _curr = 0; public void Operation(char @operator, int operand) { switch (@operator) { case '+': _curr += operand; break; case '-': _curr -= operand; break; case '*': _curr *= operand; break; case '/': _curr /= operand; break; } Console.WriteLine("Current value = {0,3} (following {1} {2})", _curr, @operator, operand); } }}
Command相当于命令
/* *创建人:王雅瑾 *创建日期:2014/7/31 10:47:24 *说明: *版权所有: */using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Calculator{ abstract class Command { public abstract void Execute(); public abstract void UnExecute(); } class CalculatorCommand : Command { private char _operator; private int _operand; private Calculator _calculator; public CalculatorCommand(Calculator calculator, char @operator, int operand) { this._calculator = calculator; this._operator = @operator; this._operand = operand; } public char Operator { set { _operator = value; } } public int Operand { set { _operand = value; } } public override void Execute() { _calculator.Operation(_operator ,_operand ); } public override void UnExecute() { _calculator.Operation(Undo(_operator), _operand); } private char Undo(char @operator) { switch (@operator) { case '+': return '-'; case '-': return '+'; case '*': return '/'; case '/': return '*'; default: throw new ArgumentException("@operator"); } } }}
User相当于是服务员
/* *创建人:王雅瑾 *创建日期:2014/7/31 11:10:33 *说明: *版权所有: */using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Calculator{ class User { private Calculator _calculator = new Calculator(); private List<Command> _commands = new List<Command>(); private int _current = 0; public void Redo(int levels){ Console.WriteLine("\n---- Redo {0} levels ", levels); for (int i = 0; i < levels; i++) { if (_current < _commands.Count ) { Command command = _commands[_current++]; command.Execute(); } } } public void Undo(int levels) { Console.WriteLine("\n---- Undo {0} levels ", levels); for (int i = 0; i < levels; i++) { if (_current > 0) { Command command = _commands[--_current] as Command; command.UnExecute(); } } } public void Compute(char @operator, int operand) { Command command = new CalculatorCommand(_calculator ,@operator,operand); command.Execute(); _commands.Add(command); _current++; } }}
Program相当于客户端类
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Calculator{ class Program { static void Main(string[] args) { User user = new User(); user.Compute('+', 100); user.Compute('-', 50); user.Compute('*', 10); user.Compute('/', 2); user.Undo(4); user.Redo(4); Console.ReadKey(); } }}
思考:命令模式和组合模式一起实现宏命令类
命令模式和备忘录模式一起撤退和重做的操作。
总结:有了理论之后多加实践才能真正理解设计模式。
- 命令模式再学习
- 设计模式学习--命令模式
- 设计模式学习-----命令模式
- 设计模式学习--命令模式
- 设计模式学习--命令模式
- 学习设计模式-命令模式
- 设计模式学习:命令模式
- 命令模式学习
- sublime命令模式学习
- 设计模式学习-Command(命令)
- headfirst学习笔记/命令模式
- 命令模式学习和思考
- 设计模式学习10 -- 命令模式
- 设计模式学习笔记之命令模式
- 设计模式学习--命令模式(command)
- <大话设计模式学习一>命令模式
- 设计模式学习总结(18) 命令模式
- 设计模式学习笔记之命令模式
- 静态库和动态库冲突
- ScrollView子View为自定义View时需要注意的几点问题
- scanf为什么有时用取地址符,有时不用---取址符:&
- WPF 中style文件的引用
- PHP设计模式--策略模式
- 命令模式再学习
- python 获取省份的天气预报
- POJ 1503 Integer Inquiry(高精度)
- 郑漂一族,我是程序员,我的未来我做主
- 贪心算法(Greedy Algorithms)
- QT5静态编译教程,主要针对vs2012
- 转载:disruptor简介
- Thrift框架中函数栈的大小对程序的影响
- Errors running builder 'DeploymentBuilder' on project '