- 浏览: 145229 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
jackroomage:
-HashMap 类 (除了不同步和允许使用 null ...
map,set,list,等JAVA中集合解析 -
bin_1715575332:
讲得很形象,呵呵。
Spring如何实现IOC与AOP的 -
love_miaohong:
表达的很清晰!
map,set,list,等JAVA中集合解析 -
Wuaner:
引用 4,sleep必须捕获异常,而wait,notify和n ...
sleep() 和 wait() 的区别 -
javawen:
dadsdddddd
java 异常类
3.7 命令模式的优缺点
- 更松散的耦合
命令模式使得发起命令的对象——客户端,和具体实现命令的对象——接收者对象完全解耦,也就是说发起命令的对象,完全不知道具体实现对象是谁,也不知道如何实现。 - 更动态的控制
命令模式把请求封装起来,可以动态对它进行参数化、队列化和日志化等操作,从而使得系统更灵活。 - 能很自然的复合命令
命令模式中的命令对象,能够很容易的组合成为复合命令,就是前面讲的宏命令,从而使系统操作更简单,功能更强大。 - 更好的扩展性
由于发起命令的对象和具体的实现完全解耦,因此扩展新的命令就很容易,只需要实现新的命令对象,然后在装配的时候,把具体的实现对象设置到命令对象里面,然后就可以使用这个命令对象,已有的实现完全不用变化。
3.8 思考命令模式
1:命令模式的本质
命令模式的本质:封装请求
。
前面讲了,命令模式的关键就是把请求封装成为命令对象,然后就可以对这个对象进行一系列的处理了,比如上面讲到的参数化配置、可撤销操作、宏命令、队列请求、日志请求等功能处理。
2:何时选用命令模式
建议在如下情况中,选用命令模式:
- 如果需要抽象出需要执行的动作,并参数化这些对象,可以选用命令模式,把这些需要执行的动作抽象成为命令,然后实现命令的参数化配置
- 如果需要在不同的时刻指定、排列和执行请求,可以选用命令模式,把这些请求封装成为命令对象,然后实现把请求队列化
- 如果需要支持取消操作,可以选用命令模式,通过管理命令对象,能很容易的实现命令的恢复和重做的功能
- 如果需要支持当系统崩溃时,能把对系统的操作功能重新执行一遍,可以选用命令模式,把这些操作功能的请求封装成命令对象,然后实现日志命令,就可以在系统恢复回来后,通过日志获取命令列表,从而重新执行一遍功能
- 在需要事务的系统中,可以选用命令模式,命令模式提供了对事务进行建模的方法,命令模式有一个别名就是Transaction。
3.9 退化的命令模式
在领会了命令模式本质后,来思考一个命令模式退化的情况。
前面讲到了智能命令,如果命令的实现对象超级智能,实现了命令所要求的功能,那么就不需要接收者了,既然没有了接收者,那么也就不需要组装者了。
(1)举个最简单的示例来说明
比如现在要实现一个打印服务,由于非常简单,所以基本上就没有什么讲述,依次来看,命令接口定义如下:
- public interface Command {
- public void execute();
- }
public interface Command { public void execute(); }
命令的实现示例代码如下:
- public class PrintService implements Command{
- /**
- * 要输出的内容
- */
- private String str = "" ;
- /**
- * 构造方法,传入要输出的内容
- * @param s 要输出的内容
- */
- public PrintService(String s){
- str = s;
- }
- public void execute() {
- //智能的体现,自己知道怎么实现命令所要求的功能,并真的实现了相应的功能,不再转调接收者了
- System.out.println("打印的内容为=" +str);
- }
- }
public class PrintService implements Command{ /** * 要输出的内容 */ private String str = ""; /** * 构造方法,传入要输出的内容 * @param s 要输出的内容 */ public PrintService(String s){ str = s; } public void execute() { //智能的体现,自己知道怎么实现命令所要求的功能,并真的实现了相应的功能,不再转调接收者了 System.out.println("打印的内容为="+str); } }
此时的Invoker示例代码如下:
- public class Invoker {
- /**
- * 持有命令对象
- */
- private Command cmd = null ;
- /**
- * 设置命令对象
- * @param cmd 命令对象
- */
- public void setCmd(Command cmd){
- this .cmd = cmd;
- }
- /**
- * 开始打印
- */
- public void startPrint(){
- //执行命令的功能
- this .cmd.execute();
- }
- }
public class Invoker { /** * 持有命令对象 */ private Command cmd = null; /** * 设置命令对象 * @param cmd 命令对象 */ public void setCmd(Command cmd){ this.cmd = cmd; } /** * 开始打印 */ public void startPrint(){ //执行命令的功能 this.cmd.execute(); } }
最后看看客户端的代码,示例如下:
- public class Client {
- public static void main(String[] args) {
- //准备要发出的命令
- Command cmd = new PrintService( "退化的命令模式示例" );
- //设置命令给持有者
- Invoker invoker = new Invoker();
- invoker.setCmd(cmd);
- //按下按钮,真正启动执行命令
- invoker.startPrint();
- }
- }
public class Client { public static void main(String[] args) { //准备要发出的命令 Command cmd = new PrintService("退化的命令模式示例"); //设置命令给持有者 Invoker invoker = new Invoker(); invoker.setCmd(cmd); //按下按钮,真正启动执行命令 invoker.startPrint(); } }
测试结果如下:
- 打印的内容为=退化的命令模式示例
打印的内容为=退化的命令模式示例
(2)继续变化
如果此时继续变化,Invoker也开始变得智能化,在Invoker的startPrint方法里面,Invoker加入了一些实现,同时
Invoker对持有命令也有意见,觉得自己是个傀儡,要求改变一下,直接在调用方法的时候传递命令对象进来,示例代码如下:
- public class Invoker {
- public void startPrint(Command cmd){
- System.out.println("在Invoker中,输出服务前" );
- cmd.execute();
- System.out.println("输出服务结束" );
- }
- }
public class Invoker { public void startPrint(Command cmd){ System.out.println("在Invoker中,输出服务前"); cmd.execute(); System.out.println("输出服务结束"); } }
看起来Invoker退化成一个方法了。
这个时候Invoker很高兴,宣称自己是一个智能的服务,不再是一个傻傻的转调者,而是有自己功能的服务了。这个时候Invoker调用命令对象的执行
方法,也不叫转调,改名叫“回调”,意思是在我Invoker需要的时候,会回调你命令对象,命令对象你就乖乖的写好实现,等我“回调”你就可以了。
事实上这个时候的命令模式的实现,基本上就等同于Java回调机制的实现,可能有些朋友看起来感觉还不是佷像,那是因为在Java回调机制的常见实现上,经常没有单独的接口实现类,而是采用匿名内部类的方式来实现的。
(3)再进一步
把单独实现命令接口的类改成用匿名内部类实现,这个时候就只剩下命令的接口、Invoker类,还有客户端了。
为了使用匿名内部类,还要设置要输出的值,对命令接口做点小改动,增加一个设置输出值的方法,示例代码如下:
- public interface Command {
- public void execute();
- /**
- * 设置要输出的内容
- * @param s 要输出的内容
- */
- public void setStr(String s);
- }
public interface Command { public void execute(); /** * 设置要输出的内容 * @param s 要输出的内容 */ public void setStr(String s); }
此时Invoker就是上面那个,而客户端会有些改变,客户端的示例代码如下:
- public class Client {
- public static void main(String[] args) {
- //准备要发出的命令,没有具体实现类了
- //匿名内部类来实现命令
- Command cmd = new Command(){
- private String str = "" ;
- public void setStr(String s){
- str = s;
- }
- public void execute() {
- System.out.println("打印的内容为=" +str);
- }
- };
- cmd.setStr("退化的命令模式类似于Java回调的示例" );
- //这个时候的Invoker或许该称为服务了
- Invoker invoker = new Invoker();
- //按下按钮,真正启动执行命令
- invoker.startPrint(cmd);
- }
- }
public class Client { public static void main(String[] args) { //准备要发出的命令,没有具体实现类了 //匿名内部类来实现命令 Command cmd = new Command(){ private String str = ""; public void setStr(String s){ str = s; } public void execute() { System.out.println("打印的内容为="+str); } }; cmd.setStr("退化的命令模式类似于Java回调的示例"); //这个时候的Invoker或许该称为服务了 Invoker invoker = new Invoker(); //按下按钮,真正启动执行命令 invoker.startPrint(cmd); } }
运行测试一下,结果如下:
- 在Invoker中,输出服务前
- 打印的内容为=退化的命令模式类似于Java回调的示例
- 输出服务结束
在Invoker中,输出服务前 打印的内容为=退化的命令模式类似于Java回调的示例 输出服务结束
(4)现在是不是看出来了,这个时候的命令模式的实现,基本上就等同于Java回调机制的实现。这也是很多人大谈特谈命令模式可以实现Java回调的意思。
当然更狠的是连Invoker也不要了,直接把那个方法搬到Client中,那样测试起来就更方便了。在实际开发中,应用命令模式来实现回调机制的时
候,Invoker通常还是有的,但可以智能化实现,更准确的说Invoker充当客户调用的服务实现,而回调的方法只是实现服务功能中的一个或者几个步
骤。
3.10 相关模式
- 命令模式和组合模式
这两个模式可以组合使用。
在命令模式中,实现宏命令的功能,就可以使用组合模式来实现。前面的示例并没有按照组合模式来做,那是为了保持示例的简单,还有突出命令模式的实现,这点请注意。 - 命令模式和备忘录模式
这两个模式可以组合使用。
在命令模式中,实现可撤销操作功能时,前面讲了有两种实现方式,其中有一种就是保存命令执行前的状态,撤销的时候就把状态恢复回去。如果采用这种方式实现,就可以考虑使用备忘录模式。
如果状态存储在命令对象里面,那么还可以使用原型模式,把命令对象当作原型来克隆一个新的对象,然后把克隆出来的对象通过备忘录模式存放。 - 命令模式和模板方法模式
这两个模式从某种意义上有相似的功能,命令模式可以作为模板方法的一种替代模式,也就是说命令模式可以模仿实现模板方法模式的功能。
如同前面讲述的退化的命令模式可以实现Java的回调,而Invoker智能化后向服务进化,如果Invoker的方法就是一个算法骨架,其中有两步在这个骨架里面没有具体实现,需要外部来实现,这个时候就可以通过回调命令接口来实现。
而类似的功能在模板方法里面,一个算法骨架,其中有两步在这个骨架里面没有具体实现,是先调用抽象方法,然后等待子类来实现。
可以看出虽然实现方式不一样,但是可以实现相同的功能。
命令模式结束,谢谢您的捧场,鞠躬ing!!!
转载自:http://chjavach.iteye.com/blog/719371
发表评论
-
研磨设计模式之简单工厂模式-3(转)
2011-03-22 15:25 8563 模式讲解 3.1 典型 ... -
研磨设计模式之简单工厂模式-2(转)
2010-11-19 16:17 7422 解决方案 1 简单工厂来解决 ... -
研磨设计模式之简单工厂模式-1(转)
2010-11-19 16:02 740继续研磨设计模式, ... -
研磨设计模式之抽象工厂模式-1(转)
2010-10-28 15:58 820抽象工厂模式(Abstract Factory) 1.1 ... -
研磨设计模式之装饰模式-4(转)
2010-10-19 16:41 8583.3 装饰模式和AOP 装饰模式和A ... -
研磨设计模式之装饰模式-3(转)
2010-10-11 09:35 7483 模式讲解 3.1 认识 ... -
研磨设计模式之装饰模式-2(转)
2010-09-28 15:42 8242 解决方案 2.1 装饰 ... -
研磨设计模式之装饰模式-1(转)
2010-09-26 08:49 895装饰模式(Decorator) 1 ... -
研磨设计模式之桥接模式-4(转)
2010-09-09 19:03 8973.4 广义桥接-Java中无 ... -
研磨设计模式之桥接模式-3(转)
2010-09-09 18:43 5873 模式讲解 3.1 认识 ... -
研磨设计模式之工厂方法模式-5(转)
2010-09-07 20:01 8453.3 平行的类层次结 ... -
研磨设计模式之工厂方法模式-4(转)
2010-09-07 19:26 6133.2 工厂方法模式与Io ... -
研磨设计模式之工厂方法模式-3(转)
2010-09-07 19:03 6223 模式讲解 3.1 认识工厂方法模式 (1)模式 ... -
研磨设计模式之工厂方法模式-2(转)
2010-09-07 18:22 7622 解决方案 2.1 工 ... -
研磨设计模式之工厂方法模式-1(转)
2010-09-03 18:43 678做Java一晃就十年了,最 ... -
研磨设计模式之策略模式-6(转)
2010-09-02 19:04 10373.4 策略模式结合模板方法模式 在实 ... -
研磨设计模式之策略模式-5(转)
2010-09-02 18:46 735接策略模式-4,其实是讲的一个主题,写在一个里面超长了,只 ... -
研磨设计模式之策略模式-4(转)
2010-09-02 18:29 7843.3 Context和Strategy的 ... -
研磨设计模式之策略模式-3(转)
2010-09-02 17:42 7053 模式讲解 3.1 认 ... -
研磨设计模式之策略模式-2(转)
2010-09-02 17:30 7652 解决方案 2.1 策 ...
相关推荐
《研磨设计模式》是一本深入探讨软件设计原则与实践的经典书籍,其配套源代码提供了丰富的实例,帮助读者更好地理解和应用各种设计模式。这个UTF-8格式的压缩包包含了书中介绍的各种设计模式的实现,是学习和研究...
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...
研磨设计模式的过程是持续学习和实践的过程,chjavach的博客文章提供了深入探讨这些模式的宝贵资源,值得我们仔细阅读和学习。通过深入理解和运用这些设计模式,可以提升个人的编程技巧,同时也为团队合作和项目维护...
《研磨设计模式》这本书是陈臣和王斌两位作者合作的成果,专注于讲解软件设计中的模式应用。设计模式是软件工程中的一种最佳实践,它总结了在特定上下文中解决问题的常见方法,使得开发者可以复用这些解决方案,提高...
《研磨设计模式》这本书是软件开发领域中的经典之作,主要关注的是面向对象设计中的设计模式。设计模式是在特定上下文中解决常见问题的最佳实践,它为开发者提供了在类似情况下重复使用解决方案的模板,有助于提高...
这个“研磨设计模式博文集”显然是一份深入探讨设计模式的资料集合,其中可能包含了对多种设计模式的详细解析、示例代码以及实际应用中的经验分享。在软件开发中,设计模式能够帮助开发者提高代码质量、可读性和可...
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...
"研磨设计模式 演示源代码"这个资源包含了对设计模式的详细解释和实例分析,旨在帮助学习者深入理解和应用这些模式。 1. **单例模式**:确保一个类只有一个实例,并提供一个全局访问点。在资源管理、缓存或者线程池...
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...
这个名为“研磨设计模式视频课程PPT”的压缩包包含了一份关于23种核心设计模式的详细教学资料,旨在帮助开发者提升软件设计的效率和可维护性。下面将对这些设计模式进行深入解析。 1. **单例模式(Singleton)**:...
这篇“设计模式学习心得(研磨设计模式)”博客及其相关的PDF文档,为我们提供了一个深入理解和应用设计模式的宝贵资源。以下将针对单例模式、工厂方法模式、策略模式、命令模式和桥接模式进行详细讲解。 1. **单例...
《研磨设计模式》实战是IT领域中关于软件设计的一份重要资料,它主要探讨了设计模式在实际项目中的应用。设计模式是软件工程中经过长期实践总结出的通用问题解决方案,是解决常见设计问题的经验总结。这份PPT可能是...
Java的研磨设计模式是将这些模式应用到Java编程中的具体体现,它能够帮助开发者编写出更加灵活、可维护和可扩展的代码。本篇文章将深入探讨设计模式的核心概念,并通过Java实例来解析这些模式。 1. 单例模式:确保...
设计模式Golang实现《研磨设计模式》读书笔记Go语言设计模式Go语言设计模式的实例代码创建模式工厂简单模式(Simple Factory)工厂方法模式(工厂方法)抽象工厂模式(Abstract Factory)创建者模式(Builder)原型...
研磨设计模式系列包括单例模式、工厂方法模式、策略模式、命令模式和桥接模式等多种模式,每种模式都有其特点和应用场景。 单例模式 单例模式是一种创建型模式,用于限制一个类的实例化只能产生一个对象。单例模式...
"研磨设计模式视频课程PPT"是一套专门针对设计模式的学习资料,其目标是帮助开发者深入理解和应用这些模式。 本课程可能涵盖了以下主要的设计模式类别: 1. 创建型模式:这类模式涉及到对象的创建,如单例模式...
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...