`

JAVA设计模式学习——命令模式

 
阅读更多

转自:http://alaric.iteye.com/blog/1927894


命令(Command)模式:又称Action模式或者Transaction模式。它属于对象的行为模式。命令模式把一个请求或者操作封装到一个对象中。命令模式允许系统使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和撤销功能。
GoF命令模式结构图如下:



命令模式是有以下角色:
抽象命令(Command)角色:声明执行操作的接口。
具体命令(ConcreteCommand)角色:将一个接收者对象绑定到一个动作上。调用接收者相应的操作,以实现Execute方法。
客户端(Client)角色:创建一个命令对象并设定它的接收者。
请求者(Invoker)角色:负责调用命令对象的执行请求;
接收者(Receiver)角色:负责具体实施和执行一个请求相关的操作。任何一个类都可以作为一个接收者。
上面模型的模拟代码如下:
Java代码 收藏代码
  1. packagecommand;
  2. /**
  3. *
  4. *作者:alaric
  5. *时间:2013-8-20下午7:39:48
  6. *描述:接收者角色
  7. */
  8. publicclassReceiver{
  9. publicReceiver(){
  10. super();
  11. }
  12. /**
  13. *
  14. *作者:alaric
  15. *时间:2013-8-20下午7:40:00
  16. *描述:行动方法
  17. */
  18. publicvoidaction(){
  19. System.out.println("接收者接到命令,开始行动");
  20. }
  21. }
Java代码 收藏代码
  1. packagecommand;
  2. /**
  3. *
  4. *作者:alaric
  5. *时间:2013-8-20下午7:36:51
  6. *描述:抽象命令角色
  7. */
  8. publicinterfaceCommand{
  9. /**
  10. *
  11. *作者:alaric
  12. *时间:2013-8-20下午7:36:40
  13. *描述:执行方法
  14. */
  15. publicvoidexecute();
  16. }
Java代码 收藏代码
  1. packagecommand;
  2. /**
  3. *
  4. *作者:alaric
  5. *时间:2013-8-20下午7:37:10
  6. *描述:具体命令角色
  7. */
  8. publicclassConcreteCommandimplementsCommand{
  9. privateReceiverreceiver;
  10. publicConcreteCommand(Receiverreceiver){
  11. super();
  12. this.receiver=receiver;
  13. }
  14. @Override
  15. publicvoidexecute(){
  16. receiver.action();
  17. }
  18. }
Java代码 收藏代码
  1. packagecommand;
  2. /**
  3. *
  4. *作者:alaric
  5. *时间:2013-8-20下午7:41:07
  6. *描述:
  7. */
  8. publicclassInvoker{
  9. privateCommandcommand;
  10. publicInvoker(Commandcommand){
  11. super();
  12. this.command=command;
  13. }
  14. publicvoidaction(){
  15. command.execute();
  16. }
  17. }
Java代码 收藏代码
  1. packagecommand;
  2. /**
  3. *
  4. *作者:alaric
  5. *时间:2013-8-20下午7:33:51
  6. *描述:客户端角色
  7. */
  8. publicclassClient{
  9. /**
  10. *作者:alaric
  11. *时间:2013-8-20下午7:33:44
  12. *描述:
  13. */
  14. publicstaticvoidmain(String[]args){
  15. Receiverreceiver=newReceiver();
  16. Commandcommand=newConcreteCommand(receiver);
  17. Invokerinvoker=newInvoker(command);
  18. invoker.action();
  19. }
  20. }
命令模式是对命令的封装,它把发出命令的责任和执行命令的责任分隔开,委派给不同的对象。每一个命令都是一个操作,请求的一方发出请求要求执行一个操作;接收的一方收到请求并执行操作。命令模式允许请求的一方和接收的一方独立开来,使得请求的一方不必知道接收请求的一方接口,更不必知道请求是怎么被接收,以及操作是否被执行,何时被执行,以及是怎么被执行的。命令允许请求方和接收方各自都能独立演化,从而具有以下优点:
1、命令模式使新的命令在不改变现有结构代码的情况下很容易被加入到系统里;
2、允许接收请求的一方决定是否否决请求;
3、能较容易地设计一个命令队列;
4、可以容易地实现对请求的Undo和Redo操作;
5、在需要的情况下以较容易地将命令记入日志。
在讲门面模式的时候曾经提过一个例子,我们小时玩过投币的那种游戏机,一个方向操作杆,四个动作按钮,在一个操作面板上,封装了复杂的逻辑在机器内部,提供简单的操作界面,是一个门面的例子,然而每个操作发出一个命令,来控制游戏人物的运动和各种动作。方向操作杆是一个移动的命令,传入移动的方向和距离作为参数,还有出拳按键发出出拳命令,脚踢按键发出脚踢的命令,那还有组合操作命令,比如下踢腿(操作杆向下和踢脚按钮按下)。现在我们用命令模式来模拟这个场景。类的模型图如下:


如上图所示:Client相当于小时候的我们,Control相关于控制执行器,我们可以控制踢(KickCommand)、打(FistCommand)、移动(MoveCommand),这些命令的最终实现者也是接收者是游戏机(GameMachine)。
代码如下:
Java代码 收藏代码
  1. packagecommand.example;
  2. /**
  3. *
  4. *作者:alaric
  5. *时间:2013-8-21上午7:15:53
  6. *描述:接收者
  7. */
  8. publicclassGameMachine{
  9. publicvoidfist(){
  10. System.out.println("出拳");
  11. }
  12. publicvoidkick(){
  13. System.out.println("出脚");
  14. }
  15. publicvoidmove(Stringdirection){
  16. System.out.println("向"+direction+"移动");
  17. }
  18. }
Java代码 收藏代码
  1. packagecommand.example;
  2. /**
  3. *
  4. *作者:alaric
  5. *时间:2013-8-20下午10:20:35
  6. *描述:命令接口
  7. */
  8. publicinterfaceCommand{
  9. //执行方法
  10. publicvoidexecute();
  11. //这里还可以加入撤销方法,回滚方法等
  12. }
Java代码 收藏代码
  1. packagecommand.example;
  2. /**
  3. *
  4. *作者:alaric
  5. *时间:2013-8-21上午7:17:02
  6. *描述:拳打
  7. */
  8. publicclassFistCommandimplementsCommand{
  9. privateGameMachinemachine;
  10. publicFistCommand(GameMachinemachine){
  11. super();
  12. this.machine=machine;
  13. }
  14. @Override
  15. publicvoidexecute(){
  16. machine.fist();
  17. }
  18. }
Java代码 收藏代码
  1. packagecommand.example;
  2. /**
  3. *
  4. *作者:alaric
  5. *时间:2013-8-21上午7:42:21
  6. *描述:脚踢命令
  7. */
  8. publicclassKickCommandimplementsCommand{
  9. privateGameMachinemachine;
  10. publicKickCommand(GameMachinemachine){
  11. super();
  12. this.machine=machine;
  13. }
  14. @Override
  15. publicvoidexecute(){
  16. machine.kick();
  17. }
  18. }
Java代码 收藏代码
  1. packagecommand.example;
  2. /**
  3. *
  4. *作者:alaric
  5. *时间:2013-8-21上午7:17:02
  6. *描述:移动命令
  7. */
  8. publicclassMoveCommandimplementsCommand{
  9. privateGameMachinemachine;
  10. privateStringdirection;
  11. publicMoveCommand(GameMachinemachine,Stringdirection){
  12. super();
  13. this.machine=machine;
  14. this.direction=direction;
  15. }
  16. @Override
  17. publicvoidexecute(){
  18. machine.move(direction);
  19. }
  20. }
Java代码 收藏代码
  1. packagecommand.example;
  2. /**
  3. *
  4. *作者:alaric
  5. *时间:2013-8-21上午7:43:14
  6. *描述:控制类
  7. */
  8. publicclassControl{
  9. privateCommandfistCommand;
  10. privateCommandkickCommand;
  11. privateCommandmoveCommand;
  12. publicControl(CommandfistCommand,CommandkickCommand,CommandmoveCommand){
  13. super();
  14. this.fistCommand=fistCommand;
  15. this.kickCommand=kickCommand;
  16. this.moveCommand=moveCommand;
  17. }
  18. publicvoidfist(){
  19. fistCommand.execute();
  20. }
  21. publicvoidkick(){
  22. kickCommand.execute();
  23. }
  24. publicvoidmove(){
  25. moveCommand.execute();
  26. }
  27. }
Java代码 收藏代码
  1. packagecommand.example;
  2. /**
  3. *
  4. *作者:alaric
  5. *时间:2013-8-20下午9:26:42
  6. *描述:客户端角色
  7. */
  8. publicclassClient{
  9. /**
  10. *作者:alaric
  11. *时间:2013-8-20下午9:26:36
  12. *描述:测试
  13. */
  14. publicstaticvoidmain(String[]args){
  15. GameMachinemachine=newGameMachine();
  16. CommandfistCommand=newFistCommand(machine);
  17. CommandkickCommand=newKickCommand(machine);
  18. CommandmoveCommand=newMoveCommand(machine,"左");
  19. Controlcontrol=newControl(fistCommand,kickCommand,moveCommand);
  20. control.fist();
  21. control.kick();
  22. control.move();
  23. //其实在不同命令模式的情况下就是下面这样直接调用,
  24. //就会让调用者和实际命令执行者紧紧耦合在一起,还有一个好处
  25. //就是可以在
  26. //machine.fist();
  27. //machine.kick();
  28. //machine.move("左");
  29. }
  30. }

运行结果如下:

出拳

出脚

向左移动

通过上面代码可以看出,本来客户端可以直接调用接收者来执行动作的,现在在中间引入了命令,这些命令由调用者(Invoker这里是Control)来调用,从而对客户端和命令接收者解耦了,增加了命令后,使得命令除了execute方法外,可以插入很多其它动作,比如redo,undo,或者记录日志等。

分享到:
评论

相关推荐

    设计模式作业——用命令模式java语言编写的烧烤店

    在这个“设计模式作业——用命令模式java语言编写的烧烤店”项目中,我们将探讨如何运用命令模式来构建一个模拟烧烤店的系统。命令模式是一种行为设计模式,它将请求封装为一个对象,使得我们可以参数化不同的请求、...

    《java设计模式》课后习题模拟试题解答——刘伟.zip

    本资料“《java设计模式》课后习题模拟试题解答——刘伟.zip”主要涵盖了Java设计模式的学习与应用,特别是针对刘伟教授的相关课程的课后习题及模拟试题的解答。 设计模式分为三大类:创建型、结构型和行为型模式。...

    设计模式——命令模式

    命令模式是一种行为设计模式,它将请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。在软件工程中,这种模式常用于解耦发出命令的对象(调用者)与...

    《Java设计模式》刘伟 课后习题及模拟试题答案.rar

    《Java设计模式》是刘伟老师的一本经典教材,它深入浅出地讲解了软件设计中的重要概念——设计模式。设计模式是经验丰富的开发者在解决常见问题时总结出的通用解决方案,是软件开发中的智慧结晶。这本书的课后习题和...

    详解Java设计模式——命令模式

    命令模式是Java设计模式中的一种常见模式,主要用于将命令的发出者和执行者之间解耦,实现请求和执行分开。 命令模式的定义是将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化。它的主要目的是...

    java设计模式

    目录: 前 言 第一部分 大旗不挥,谁敢冲锋——热身篇 第1章 单一职责原则 1.1 我是“牛”类,我可以担任多职吗 1.2 绝杀技,打破你的传统思维 1.3 我单纯,所以我快乐 1.4 最佳实践 ...附录:23个设计模式

    java设计模式经典教程

    ### Java设计模式经典教程知识点概览 #### 一、设计模式概述 设计模式是一种软件设计方法,它为软件开发者提供了一种标准化的方式去解决常见的软件设计问题。设计模式的使用可以提高代码的可读性和可维护性,同时...

    java设计模式——告诉新手一些不知道的东西

    在编程世界中,Java设计模式是面向对象编程领域的一个重要概念,它为解决常见的软件设计问题提供了可重用的解决方案。对于新手来说,设计模式可能显得深奥难懂,但它们实际上是经验丰富的开发者用来提高代码质量、可...

    java设计模式(23种设计模式大全)

    根据提供的标题、描述以及部分内容,本文将深入探讨Java设计模式,并着重分析23种常见的设计模式,以帮助Java程序员更好地理解和应用这些模式。 ### Java设计模式概述 Java设计模式是面向对象软件设计的一种通用可...

    Java与模式(闫宏)

    《Java与模式》是闫宏大师的一部经典之作,它将古老的哲学智慧——道德经的智慧,巧妙地融入到现代编程语言Java的设计模式之中。这本书不仅深入浅出地讲解了23种经典的设计模式,还提供了丰富的实践案例,旨在帮助...

    设计模式——JAVA.docx

    ### JAVA设计模式总结之23种设计模式及六大原则 #### 一、设计模式之六大原则 ##### 总原则:开闭原则(Open Close Principle) 开闭原则是设计模式中最核心的原则之一,它强调的是软件实体(类、模块、函数等)...

    设计模式之(命令+责任链)

    本文将深入探讨两种重要的设计模式——命令模式和责任链模式,并通过Java代码实例来阐述它们的应用和实现。 首先,我们来看**命令模式**。命令模式的核心思想是将请求封装为一个对象,从而可以将命令参数化、支持...

    java设计模式(1)

    ### Java设计模式(1)——理解与应用 #### 一、设计模式概述 设计模式是在软件工程领域中,为了应对特定问题或情境而形成的最佳实践集合。这些模式可以帮助开发者更高效地解决常见问题,提高代码的可重用性和可...

    java的设计模式 《设计模式-java语言中的应用.pdf》

    设计模式是软件工程中的一种最佳实践,它是在特定上下文中解决常见问题的模板或蓝图。...通过阅读《设计模式——Java语言中的应用》这本书,你可以更深入地学习和掌握这些模式的细节及其在实际开发中的应用。

    JAVA设计模式(中文).chm

    《JAVA设计模式(中文).chm》是一部专为Java开发者准备的设计模式指南,它深入浅出地阐述了软件工程中的重要概念——设计模式。设计模式是解决常见编程问题的成熟解决方案,是经验丰富的开发者们在实践中总结出的最佳...

    JAVA设计模式.影印版

    **JAVA设计模式——核心概念与应用** 设计模式是软件开发中的宝贵经验总结,它们是针对常见问题的可重用解决方案。在Java编程中,设计模式是提升代码质量、可维护性和扩展性的关键。《JAVA设计模式.影印版》这本书...

    Java和Android源码设计模式

    #### 前言:迈向精通之路——设计模式的重要性 在软件开发领域,设计模式被视为提升代码质量和可维护性的关键工具。本文将深入探讨Java和Android开发中常用的设计模式,并结合实际案例进行解析,帮助读者理解和应用...

Global site tag (gtag.js) - Google Analytics