`
newleague
  • 浏览: 1504726 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类

深入浅出java命令模式

 
阅读更多

一、引言

 

忙里偷闲,终于动笔了。命令模式是从界面设计中提取出来的一种分离耦合,提高重用的方法。被认为是最优雅而且简单的模式,它的应用范围非常广泛。让我们一起来认识下它吧。

 

先从起源说起。在设计界面时,大家可以注意到这样的一种情况,同样的菜单控件,在不同的应用环境中的功能是完全不同的;而菜单选项的某个功能可能和鼠标右键的某个功能完全一致。按照最差、最原始的设计,这些不同功能的菜单、或者右键弹出菜单是要分开来实现的,你可以想象一下,word文档上面的一排菜单要实现出多少个“形似神非”的菜单类来?这完全是行不通的。这时,就要运用分离变化与不变的因素,将菜单触发的功能分离出来,而制作菜单的时候只是提供一个统一的触发接口。这样修改设计后,功能点可以被不同的菜单或者右键重用;而且菜单控件也可以去除变化因素,很大的提高了重用;而且分离了显示逻辑和业务逻辑的耦合。这便是命令模式的雏形。

 

下面我们将仔细的讨论下命令模式。

 

 

二、定义与结构

 

《设计模式》中命令模式的定义为:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。

 

看起来,命令模式好像神通广大。其实命令模式的以上功能还要看你是怎么写的——程序总是程序员写出来的,你写啥它才能干啥:)

 

       在我看来,其实命令模式像很多设计模式一样——通过在你的请求和处理之间加上了一个中间人的角色,来达到分离耦合的目的。通过对中间人角色的特殊设计来形成不同的模式。当然命令模式就是一种特殊设计的结果。

 

       看下命令模式是有哪些角色来组成的吧。             

 

1
)        命令角色(Command):声明执行操作的接口。有java接口或者抽象类来实现。

 

2
)        具体命令角色(Concrete Command):将一个接收者对象绑定于一个动作;调用接收者相应的操作,以实现命令角色声明的执行操作的接口。

 

3
)        客户角色(Client):创建一个具体命令对象(并可以设定它的接收者)。

 

4
)        请求者角色(Invoker):调用命令对象执行这个请求。

 

5
)        接收者角色(Receiver):知道如何实施与执行一个请求相关的操作。任何类都可能作为一个接收者。

 

 

以下是命令模式的类图,从中可以大致的了解到各个角色之间是怎么来协调工作的。

 

 

 

三、举例

 

本来想接着我的JUnit分析来讲解命令模式。但是由于在JUnit中,参杂了其它的模式在里面,使得命令模式的特点不太明显。所以这里将以命令模式在Web开发中最常见的应用——Struts中Action的使用作为例子。

 

在Struts中Action控制类是整个框架的核心,它连接着页面请求和后台业务逻辑处理。按照框架设计,每一个继承自Action的子类,都实现execute方法——调用后台真正处理业务的对象来完成任务。

 

注:继承自DispatchAction的子类,则可以一个类里面处理多个类似的操作。这个在这不做讨论。

 

       下面我们将Struts中的各个类与命令模式中的角色对号入座。

 

       先来看下命令角色——Action控制类

 

public class
 Action {

       ……

         
/*


         *可以看出,Action中提供了两个版本的执行接口,而且实现了默认的空实现。

       
*/

public ActionForward execute( ActionMapping mapping,

                                                  ActionForm form,

                                                  ServletRequest request,

                                                  ServletResponse response)

        
throws
 Exception {

        
try
 {

            
return
 execute(mapping, form, (HttpServletRequest) request,

                                     (HttpServletResponse) response);

        } 
catch
 (ClassCastException e) {

            
return null
;

        }

    }

 

public
 ActionForward execute( ActionMapping mapping,

                                                  ActionForm form,

                                                   HttpServletRequest request,

                                                  HttpServletResponse response)

        
throws
 Exception {

        
return null
;

    }

}

 

下面的就是请求者角色,它仅仅负责调用命令角色执行操作。

public class
 RequestProcessor {

……

protected
 ActionForward processActionPerform(HttpServletRequest request,

                                                        HttpServletResponse response,

                                                       Action action,

                                                       ActionForm form,

                                                       ActionMapping mapping)

        
throws
 IOException, ServletException {

        
try
 {

            
return
 (action.execute(mapping, form, request, response));

        } 
catch
 (Exception e) {

            
return
 (processException(request, response,e, form, mapping));

        }

}

}

 

Struts框架为我们提供了以上两个角色,要使用struts框架完成自己的业务逻辑,剩下的三个角色就要由我们自己来实现了。步骤如下:

1
)        很明显我们要先实现一个Action的子类,并重写execute方法。在此方法中调用业务模块的相应对象来完成任务。

2
)        实现处理业务的业务类。

3)        配置struts-
config.xml配置文件,将自己的Action和Form以及相应页面结合起来。

4
)        编写jsp,在页面中显式的制定对应的处理Action。

一个完整的命令模式就介绍完了。当你在页面上提交请求后,Struts框架会根据配置文件中的定义,将你的Action对象作为参数传递给RequestProcessor类中的processActionPerform()方法,由此方法调用Action对象中的执行方法,进而调用业务层中的接收角色。这样就完成了请求的处理。

 

四、Undo、事务及延伸

 

在定义中提到,命令模式支持可撤销的操作。而在上面的举例中并没有体现出来。其实命令模式之所以能够支持这种操作,完全得益于在请求者与接收者之间添加了中间角色。为了实现undo功能,首先需要一个历史列表来保存已经执行过的具体命令角色对象;修改具体命令角色中的执行方法,使它记录更多的执行细节,并将自己放入历史列表中;并在具体命令角色中添加undo方法,此方法根据记录的执行细节来复原状态(很明显,首先程序员要清楚怎么来实现,因为它和execute的效果是一样的)。

 

同样,redo功能也能够照此实现。

 

命令模式还有一个常见的用法就是执行事务操作。这就是为什么命令模式还叫做事务模式的原因吧。它可以在请求被传递到接收者角色之前,检验请求的正确性,甚至可以检查和数据库中数据的一致性,而且可以结合组合模式的结构,来一次执行多个命令。

 

使用命令模式不仅仅可以解除请求者和接收者之间的耦合,而且可以用来做批处理操作,这完全可以发挥你自己的想象——请求者发出的请求到达命令角色这里以后,先保存在一个列表中而不执行;等到一定的业务需要时,命令模式再将列表中全部的操作逐一执行。

 

哦,命令模式实在太灵活了。真是一个很有用的东西啊!

 

 

五、优点及适用情况

 

由上面的讲解可以看出命令模式有以下优点:

1
)        命令模式将调用操作的请求对象与知道如何实现该操作的接收对象解耦。

2
)        具体命令角色可以被不同的请求者角色重用。

3
)        你可将多个命令装配成一个复合命令。

4
)        增加新的具体命令角色很容易,因为这无需改变已有的类。

GOF总结了命令模式的以下适用环境。

1
)        需要抽象出待执行的动作,然后以参数的形式提供出来——类似于过程设计中的回调机制。而命令模式正是回调机制的一个面向对象的替代品。

2
)        在不同的时刻指定、排列和执行请求。一个命令对象可以有与初始请求无关的生存期。

3
)        需要支持取消操作。

4
)        支持修改日志功能。这样当系统崩溃时,这些修改可以被重做一遍。

5
)        需要支持事务操作。

 

六、总结

 

命令模式是一个很有用的模式,希望这篇文章能给你实质性的帮助。谢谢大家指正。 v

分享到:
评论

相关推荐

    深入浅出java设计模式(高清中文PDF)

    在深入浅出Java设计模式的高清中文PDF文件中,首先以一个生活化的例子引出了工厂模式的概念,介绍了工厂模式在面向对象编程中的重要性和实用性。文档详细讲解了20多种Java设计模式,并且在讲解的过程中包含了丰富的...

    深入浅出设计模式附书源码Java版源码

    深入浅出设计模式附书源码Java版源代码,是面向Java开发者的宝贵资源,旨在帮助他们理解和实践各种设计模式。这本书籍的源代码提供了实际的示例,使得学习过程更具互动性和实践性。 设计模式的核心思想是将常见的...

    深入浅出设计模式(HEAD_FIRST设计模式)电子书+java代码

    总结来说,《深入浅出设计模式》是一本以易懂的方式介绍设计模式的优秀教材,结合书中给出的Java代码,无论你是Java开发者还是其他语言的程序员,都能从中受益,掌握设计模式这一核心的软件工程技能。通过学习本书,...

    深入浅出设计模式(源代码c# 和JAVA)

    《深入浅出设计模式》是一本旨在帮助开发者理解和应用设计模式的经典书籍,它提供了C#和JAVA两种语言的源代码实现,使得学习者可以通过实际操作来加深对设计模式的理解。 1. **设计模式的基本概念**: 设计模式...

    深入浅出设计模式(中文版)

    《深入浅出设计模式》是一本专为Java开发者编写的关于设计模式的中文教材,它旨在帮助读者理解和掌握设计模式这一编程领域的核心概念。设计模式是软件开发中的经验总结,是解决常见问题的有效模板,通过将成熟的设计...

    深入浅出Java 23种设计模式.rar

    本资料"深入浅出Java 23种设计模式"旨在帮助开发者理解和应用这23种经典设计模式。 首先,我们要了解设计模式的三大类别:创建型模式、结构型模式和行为型模式。创建型模式关注对象的创建过程,如单例模式...

    深入浅出设计模式(Java版)

    《深入浅出设计模式(Java版)》这本书是面向Java开发者的一本全面解析设计模式的指南。它深入探讨了各种设计模式,旨在帮助读者更好地理解和应用这些模式来提高代码的可读性、可维护性和可扩展性。以下是该书可能...

    深入浅出设计模式(中文版电子版)

    5.2CommandPattern(命令模式) 179 5.2.1定义 179 5.2.2现实中的实例——餐馆订菜 180 5.2.3C#实例——简单计算器 181 5.2.4Java实例——总开关 185 5.2.5优势和缺陷 189 5.2.6应用情景 189 5.3Interpreter...

    深入浅出设计模式样章

    《深入浅出设计模式样章》是一本专为软件开发者准备的指南,旨在帮助读者理解和掌握设计模式这一核心编程概念。设计模式是软件工程中经过时间验证、在特定情境下解决常见问题的有效方法,它提供了可重用的解决方案,...

    Eclipse rcp深入浅出中英文版及配套代码

    《Eclipse RCP深入浅出》一书,无论中文版还是英文版,都是为了帮助开发者更好地理解和掌握这一技术。 本书深入探讨了Eclipse RCP的各个关键概念和技术,包括但不限于以下内容: 1. **基础架构**:Eclipse RCP的...

    深入浅出设计模式 (希望对设计模式有所了解和深入研究的都适用)

    《深入浅出设计模式》是一本旨在帮助读者理解和掌握设计模式的书籍,适合那些希望深入研究设计模式的IT从业者。这本书可能与《HEAD FIRST设计模式》相辅相成,通过不同的讲解方式来帮助读者更全面地理解这一领域。 ...

    Java与模式(闫宏)

    这本书不仅深入浅出地讲解了23种经典的设计模式,还提供了丰富的实践案例,旨在帮助读者提升软件设计的水平和代码的可维护性。 首先,我们要理解什么是设计模式。设计模式是软件工程中经过验证的、在特定情境下解决...

    深入浅出Hadoop

    《深入浅出Hadoop》这篇文章主要探讨了Hadoop这一分布式计算框架的源代码级实现,旨在帮助读者理解其内部工作原理。Hadoop是Apache软件基金会的一个开源项目,它提供了处理和存储大规模数据的能力,尤其适合大数据...

    java与模式-阎宏

    《Java与模式》是阎宏博士的一本经典著作,它深入浅出地介绍了如何在Java编程中应用设计模式。这本书不仅讲解了设计模式的基本概念,还涵盖了23种经典的GOF设计模式,并结合Java语言特性进行了详细的解释和实例演示...

Global site tag (gtag.js) - Google Analytics