java command模式_java设计模式——command 模式

意图:将一个请求封装为一个对象,从而可用不同的请求对客户进行参数化;对请求排队或记录日志,以及支持可撤销的操作

动机:将”发出请求的对象”和”接收与执行这些请求的对象”分隔开来。

效果:

1)、command模式将调用操作的对象和实现该操作的对象解耦

2)、可以将多个命令装配成一个复合命令,复合命令是Composite模式的一个实例

3)、增加新的command很容易,无需改变已有的类

适用性:

1)、抽象出待执行的动作以参数化某对象

2)、在不同的时刻指定、排列和执行请求。如请求队列

3)、支持取消操作

4)、支持修改日志

5)、用构建在原语操作上的高层操作构造一个系统。支持事物

参与者:

1)、Command

声明执行操作的接口

2)、ConcreteCommand

将一个接收者对象绑定于一个动作

调用接收者相应的操作,以实现execute

3)、Client

创建一个具体命令对象并设定它的接收者

4)、Invoker

要求该命令执行这个请求

5)、Receiver

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

结构图:

java command模式_java设计模式——command 模式_第1张图片

协作:

1)、client创建一个ConcreteCommand对象并指定它的Receiver对象

2)、某Invoker对象存储该ConcreteCommand对象

3)、该Invoker通过调用Command对象的execute操作来提交一个请求。若该命令是可撤销的,ConcreteCommand在执行execute操作前存储当前状态以用于取消该命令

4)、ConcreteCommand对象调用它的Receiver的操作以执行该请求

命令对象将动作和接受者包进对象中,这个对象只暴露出一个execute()方法,当此方法被调用的时候,接收者就会进行这些动作。从外面来看,其他对象不知道究竟哪个接收者进行了哪些动作,只知道如果调用execute()方法,请求的目的就能达到。

实例:

69c5a8ac3fa60e0848d784a6dd461da6.png

1 package com.test.patten.command;

2

3 /**

4 * 命令接口

5 */

6 public interface Command {

7 /**

8 * 执行命令

9 */

10 public void execute();

11 /**

12 * 撤销命令

13 */

14 public void undo();

15 }

69c5a8ac3fa60e0848d784a6dd461da6.png

69c5a8ac3fa60e0848d784a6dd461da6.png

1 package com.test.patten.command;

2

3 /**

4 * 命令

5 */

6 public class CreateCommand implements Command{

7 private Receiver receiver;

8 private String state;

9

10 public CreateCommand(Receiver receiver){

11 this.receiver = receiver;

12 }

13

14 @Override

15 public void execute() {

16 receiver.action();

17 }

18

19 @Override

20 public void undo() {

21 receiver.unAction();

22 }

23

24 }

69c5a8ac3fa60e0848d784a6dd461da6.png

69c5a8ac3fa60e0848d784a6dd461da6.png

1 package com.test.patten.command;

2

3 /**

4 * 命令接收者,命令真正执行人

5 */

6 public class Receiver {

7 public void action(){

8 System.out.println("执行命令...");

9 }

10

11 public void unAction(){

12 System.out.println("撤销命令...");

13 }

14 }

69c5a8ac3fa60e0848d784a6dd461da6.png

69c5a8ac3fa60e0848d784a6dd461da6.png

1 package com.test.patten.command;

2

3 public class Invoker {

4 /**

5 * 调用者持有命令对象

6 */

7 private Command command;

8

9 /**

10 * 设置命令对象

11 * @param command

12 */

13 public void setCommand(Command command) {

14 this.command = command;

15 }

16 public Command getCommand() {

17 return command;

18 }

19

20 /**

21 * 执行命令

22 */

23 public void runCommand(){

24 command.execute();

25 }

26 /**

27 * 撤销命令

28 */

29 public void unDoCommand(){

30 command.undo();

31 }

32 }

69c5a8ac3fa60e0848d784a6dd461da6.png

69c5a8ac3fa60e0848d784a6dd461da6.png

1 package com.test.patten.command;

2

3 public class Client {

4 public static void main(String[] args){

5 //创建接受者

6 Receiver receiver = new Receiver();

7 //创建命令对象,并设置它的接受者

8 Command command = new CreateCommand(receiver);

9

10 //创建调用者,将命令对象设置进去

11 Invoker invoker = new Invoker();

12 invoker.setCommand(command);

13

14 //这里可以测试一下

15 invoker.runCommand();

16 invoker.unDoCommand();

17 }

18 }

69c5a8ac3fa60e0848d784a6dd461da6.png

常见应用:

1、工作队列,线程池,日程安排

2、日志请求(系统恢复)

要点:

1、命令模式将发出请求的对象和执行请求的对象解耦

2、在被解耦的两者之间是通过命令对象进行沟通的。命令对象封装了接收者和一个或一组动作

3、调用者通过调用命令对象的execute()发出请求,这会使得接收者的动作被调用

4、调用者可以接受命令当作参数,甚至在运行时动态的进行

5、命令可以支持撤销,做法是实现一个undo()方法来回到execute()被执行前的状态

6、宏命令是命令的一种简单的延伸,允许调用多个命令。宏方法也可以支持撤销

7、实际操作时,很常见使用"聪明"命令对象,也就是直接实现了请求,而不是将工作委托给接受者(弊端?)

8、命令也可以用来实现日志和事物系统

你可能感兴趣的:(java,command模式)