文档章节

设计模式-命令模式

fengsehng
 fengsehng
发布于 2016/11/09 09:12
字数 1361
阅读 0
收藏 0

模式定义:

命令模式(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面试题汇总》微信订阅号。每天推送经典面试题和面试心得技巧,都是干货!

微信订阅号二维码如下:

这里写图片描述

参考:
http://baike.baidu.com/view/1963264.htm
http://design-patterns.readthedocs.io/zh_CN/latest/behavioral_patterns/command.html#id17
http://www.cnblogs.com/java-my-life/archive/2012/06/01/2526972.html

© 著作权归作者所有

共有 人打赏支持
fengsehng
粉丝 4
博文 284
码字总数 214494
作品 0
朝阳
程序员
私信 提问
《PHP设计模式大全》系列分享专栏

《PHP设计模式大全》已整理成PDF文档,点击可直接下载至本地查阅 https://www.webfalse.com/read/201739.html 文章 php设计模式介绍之编程惯用法第1/3页 php设计模式介绍之值对象模式第1/5页...

kaixin_code
11/06
0
0
javascript 设计模式之工厂(Factory)模式

工厂模式介绍 工厂模式是一个创建型的模式,主要就是创建对象。其中工厂模式又分为简单工厂模式和抽象工厂模式。简单工厂模式是通过工厂方法确定创建 对应类型的对象。抽象工厂模式是通过子类...

hlxiong
2014/04/14
0
0
JavaScript设计模式入坑

JavaScript设计模式入坑 介绍 设计模式编写易于维护的代码。 设计模式的开创者是一位土木工程师。Σ( ° △ °|||)︴,写代码就是盖房子。 模式 模式一种可以复用的解决方案。解决软件设计中...

小小小8021
10/18
0
0
编程中的那些经典套路——设计模式汇总

在正式阅读前,我先谈谈我们该用什么姿势和心态学习设计模式: 如果你还没有过多的编程经验(泛指半年以下),我建议你把它当做小说来看,能看懂多少是多少,因为半年以下经验的程序员用到设...

gzchen
08/27
0
0
设计模式知识汇总(附github分享)

写在前面 主要内容 为了更系统的学习设计模式,特地开了这样一个基于Java的设计模式【集中营】,都是笔者在实际工作中用到过或者学习过的一些设计模式的一些提炼或者总检。慢慢地初见规模,也...

landy8530
10/10
0
0

没有更多内容

加载失败,请刷新页面

加载更多

阿里云建站

阿里云自营建站 没想到阿里云已经切入这块市场了。可以用拖动的方式来建站的模式,真的还是6.

miaojiangmin
29分钟前
2
0
linux系统top命令:virt,res,shr详解

VIRT:virtual memory usage 虚拟内存 1、进程“需要的”虚拟内存大小,包括进程使用的库、代码、数据等 2、假如进程申请100m的内存,但实际只使用了10m,那么它会增长100m,而不是实际的使用...

刘祖鹏
35分钟前
2
0
day154-2018-11-21-英语流利阅读-待学习

快手网红发明家:百万粉丝 vs 零销量 雪梨 2018-11-21 1.今日导读 “我做了一个‘雷神锤’的斜挎包,你看这里可以打开,里面可以装手机、卫生纸、钱包,觉得轻的话可以放一些砖头。咱们把它背...

飞鱼说编程
42分钟前
10
0
图灵奖得主华人高徒发布AI芯片!64位RISC-V、高度可编程,低功耗

作为RISC-V架构下的旗手玩家,睿思芯科自然希望通过产品展现出RISC-V可编程架构的巨大潜力。 https://mbd.baidu.com/newspage/data/landingshare?context=%7B%22nid%22:%22news_917924603675...

whoisliang
42分钟前
5
0
xcode 10 缺少 libstdc++6.0.9 解决方案

image.png 本方案基于xcode10正式版操作,其它版本请自行验证! 苹果在XCode10中移除了libstdc++(libstdc++.6、libstdc++6.0.9)库。 项目解决方法:删除libstdc++(libstdc++.6、libstdc++6....

壹峰
47分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部