博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式-命令模式
阅读量:5286 次
发布时间:2019-06-14

本文共 3055 字,大约阅读时间需要 10 分钟。

模式定义:

命令模式(Command Pattern):将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。命令模式是一种对象行为型模式,其别名为动作(Action)模式或事务(Transaction)模式。

模式结构

如下图:

这里写图片描述

Command:

定义命令的接口,声明执行的方法。

ConcreteCommand:

命令接口实现对象,是“虚”的实现;通常会持有接收者,并调用接收者的功能来完成命令要执行的操作。

Receiver:

接收者,真正执行命令的对象。任何类都可能成为一个接收者,只要它能够实现命令要求实现的相应功能。

Invoker:

要求命令对象执行请求,通常会持有命令对象,可以持有很多的命令对象。这个是客户端真正触发命令并要求命令执行相应操作的地方,也就是说相当于使用命令对象的入口。

Client:

创建具体的命令对象,并且设置命令对象的接收者。注意这个不是我们常规意义上的客户端,而是在组装命令对象和接收者,或许,把这个Client称为装配者会更好理解,因为真正使用命令的客户端是从Invoker来触发执行。

模式协作

  1. Client创建一个ConcreteCommand对象并指定他的Receiver对象

  2. 某个Invoker对象存储该ConcreteCommand对象

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

  4. ConcreteCommand对象对调用它的Receiver的一些操作以执行该请求

模式动机

在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活。

命令模式可以对发送者和接收者完全解耦,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求。这就是命令模式的模式动机。

模式举例

接收者角色类

public class Receiver {
/** * 真正执行命令相应的操作 */ public void action(){ System.out.println("执行操作"); }}

抽象命令角色类

public interface Command {
/** * 执行方法 */ void execute();}

具体命令角色类

public class ConcreteCommand implements Command {

//持有相应的接收者对象    private Receiver receiver = null;    /**     * 构造方法     */    public ConcreteCommand(Receiver receiver){        this.receiver = receiver;    }    @Override    public void execute() {        //通常会转调接收者对象的相应方法,让接收者来真正执行功能        receiver.action();    }}

请求者角色类

public class Invoker {
/** * 持有命令对象 */ private Command command = null; /** * 构造方法 */ public Invoker(Command command){ this.command = command; } /** * 行动方法 */ public void action(){ command.execute(); }}

客户端角色类

public class Client {    public static void main(String[] args) {        //创建接收者        Receiver receiver = new Receiver();        //创建命令对象,设定它的接收者        Command command = new ConcreteCommand(receiver);        //创建请求者,把命令对象设置进去        Invoker invoker = new Invoker(command);        //执行方法        invoker.action();    }}

模式优点

1.降低对象之间的耦合度。

2.新的命令可以很容易地加入到系统中。

3.可以比较容易地设计一个组合命令。

4.调用同一方法实现不同的功能

模式缺点

使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。

适用环境

1.系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。

2.系统需要在不同的时间指定请求、将请求排队和执行请求。

3.系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。

4.系统需要将一组操作组合在一起,即支持宏命令。

模式扩展

宏命令又称为组合命令,它是命令模式和组合模式联用的产物。

-宏命令也是一个具体命令,不过它包含了对其他命令对象的引用,在调用宏命令的execute()方法时,将递归调用它所包含的每个成员命令的execute()方法,一个宏命令的成员对象可以是简单命令,还可以继续是宏命令。执行一个宏命令将执行多个具体命令,从而实现对命令的批处理。

我的微信二维码如下,欢迎交流讨论

这里写图片描述

欢迎关注《IT面试题汇总》微信订阅号。每天推送经典面试题和面试心得技巧,都是干货!

微信订阅号二维码如下:

这里写图片描述

参考:

<script type="text/javascript"> $(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split('\n').length; var $numbering = $('<ul/>').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('<li/>').text(i)); }; $numbering.fadeIn(1700); }); }); </script>

转载于:https://www.cnblogs.com/fengsehng/p/6048660.html

你可能感兴趣的文章
【BZOJ4033】【HAOI2015】树上染色 树形DP
查看>>
max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
查看>>
中文词频统计及词云制作
查看>>
设计模式总结
查看>>
openc下cv::Mat和IplImage的相互转换
查看>>
人生方向?【1】
查看>>
C#加密解密
查看>>
I2C Bus
查看>>
Alpha 冲刺(5/10)
查看>>
mysql开启远程连接及本地连接
查看>>
并查集,是否成树,Poj(1308)
查看>>
QueryDSL
查看>>
java实现LIS算法,出操队形问题
查看>>
51nod 1499 图(最小割)
查看>>
浮动的艺术下
查看>>
菜根谭#279
查看>>
Acne Solutions - Not All Measures are Equal
查看>>
validationEngine验证的使用
查看>>
background-size的应用情景:当给出的背景图片大于实际网页需要布局的图片大小时...
查看>>
四大布局方式
查看>>