前言

在前面的章节中,我们介绍了单例模式,它是创建型模式的一员。今天我们来介绍一下命令模式,它是行为型模式的一员。

思考题

首先,让我们来思考下面的问题:

话说有一家遥控器公司,他想制作一款很牛逼的遥控器。这个遥控器可以控制家里所有的电器,为了简单一点,假设所有的用户家里只有电视机和电灯两种电器。那么如果是你,你会怎么实现这个遥控器呢?

由于电视机和电灯是两个不同的厂商生产的产品,所以他们的打开方式是不一样的。首先让我们来看一看这两个类的定义:

Television.java:

public class Television {
public void open() {
System.out.println("打开电视");
} public void close() {
System.out.println("关闭电视");
}
}

ElectricLight.java:

public class ElectricLight {
public void on() {
System.out.println("打开电灯");
} public void off() {
System.out.println("关闭电灯");
}
}

让我们来看下下面的设计:

RemoteControl.java:

public class RemoteControl {
private String product; public void setProduct(String product) {
this.product = product;
} public void execute() {
switch (product) {
case "Television":
new Television().open();
break;
case "ElectricLight":
new ElectricLight().on();
break;
default:
}
}
}

这个遥控器太棒了,我可以用它来控制家里的电视机和电灯,再也不用到处翻找遥控器了。要是它还可以控制洗衣机那就更棒了。那么如果再在遥控器里添加一个洗衣机需要怎么做,哦,太糟糕了,我还需要把遥控器拆开,然后把洗衣机的命令添加进去,好痛苦有么有,那么有么有一种设计可以不对遥控器进行更改,就可以添加其他的家电呢。这个时候命令模式就可以发挥它的作用了。

命令模式

定义:将请求封装成对象,从而可以使用不同的请求将客户参数化,使得请求发送者和请求接受者之间互相隔离。

类图:

上面涉及到的角色有4个:

  • 抽象命令:将命令封装成一个接口,每个接收者都需要实现一个相应的命令接口。
  • 具体命令:实现了抽象命令类的方法,并且调用了具体接受者的方法。
  • 请求接受者:具体要执行操作的类。
  • 请求发送者:将命令对象传递给具体的接受者,执行相应的操作。

思考题实现

首先,定义一个抽象命令类:

Command.java:

public interface Command {
void execute();
}

然后,实现抽象命令类:

TelevisionCommand.java:

public class TelevisionCommand implements Command {
private Television television = new Television(); @Override
public void execute() {
television.open();
}
}

ElectricLightCommand.java:

public class ElectricLightCommand implements Command {
private ElectricLight electricLight = new ElectricLight(); @Override
public void execute() {
electricLight.on();
}
}

然后,实现一个遥控器:

RemoteControl.java:

public class RemoteControl {
private Command command; public void execute() {
command.execute();
} public void initCommand(Command command) {
this.command = command;
}
}

测试类:

Custom.java:

public class Custom {
public static void main(String ...args) {
RemoteControl remoteControl = new RemoteControl(); remoteControl.initCommand(new TelevisionCommand());
remoteControl.execute(); remoteControl.initCommand(new ElectricLightCommand());
remoteControl.execute();
}
}

[design pattern](8) Command的更多相关文章

  1. [Design Pattern] Command Pattern 命令模式

    发现公司的代码好像有用到 Command Pattern,回顾重温下. Command Pattern 的类图结构如下: 参考 <Head First Design Patterns(英文版)& ...

  2. 说说设计模式~大话目录(Design Pattern)

    回到占占推荐博客索引 设计模式(Design pattern)与其它知识不同,它没有华丽的外表,没有吸引人的工具去实现,它是一种心法,一种内功,如果你希望在软件开发领域有一种新的突破,一个质的飞越,那 ...

  3. 设计模式(Design Pattern)系列之.NET专题

    最近,不是特别忙,重新翻了下设计模式,特地在此记录一下.会不定期更新本系列专题文章. 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结. 使用 ...

  4. [转]Design Pattern Interview Questions - Part 4

    Bridge Pattern, Composite Pattern, Decorator Pattern, Facade Pattern, COR Pattern, Proxy Pattern, te ...

  5. [转]Design Pattern Interview Questions - Part 1

    Factory, Abstract factory, prototype pattern (B) What are design patterns? (A) Can you explain facto ...

  6. C++ Design Pattern: What is a Design Pattern?

    Q: What is a Design Pattern? A: Design Patterns represent solutions to problems what arise when deve ...

  7. Design Pattern in Simple Examples

    Instead of defining what is design pattern lets define what we mean by design and what we mean by pa ...

  8. java设计模式大全 Design pattern samples in Java(最经典最全的资料)

    java设计模式大全 Design pattern samples in Java(最经典最全的资料) 2015年06月19日 13:10:58 阅读数:11100 Design pattern sa ...

  9. Design Principle vs Design Pattern 设计原则 vs 设计模式

    Design Principle vs Design Pattern设计原则 vs 设计模式 来源:https://www.tutorialsteacher.com/articles/differen ...

随机推荐

  1. pycharm中ctrl + C复制, ctrl+A全选等快捷键失效

    原因是:在安装pycharm的时候也同时安装了vim插件,需要在settings  - > vim Emulation里将相关的handler改成 IDE

  2. React同构起步

    React同构从0到1 前言 如果你想快速做react同构的新项目建议你去了解next.js等成熟框架,本教程仅限于想了解如何从0开始实现一个同构环境过程的同学,对于想改造现有spa项目的同学也很有帮 ...

  3. numpy数组转置与轴变换

    numpy数组转置与轴变换 矩阵的转置 >>> import numpy as np >>> arr=np.arange(15).reshape((3,5)) &g ...

  4. 滑雪(dp或记忆化搜索)

    题意:给你一个二维数组,求最长的递减路线的长度,只能向四个方向延伸. 解法1.dp[i][j]以i.j结尾的最长路线长度.边界:每个数初值为1, 转移:从四周向i.j转移,if(a[i][j]> ...

  5. 严重报错: Error configuring application listener of class org.springframework.web.context.ContextLoaderLis

    其实可能是你的jar文件没有同步发布到自己项目的lib目录中(如果你是用Maven进行构建的话) 可以试试 下面的办法 项目点击右键 点击 Properties 选择Deployment Assemb ...

  6. Struts2对于BigDecimal类型的转换问题

    Struts2对常用的数据类型如String.Integer.Double等都添加了转换器进行对应的转换操作. BigDecimal其实也算作是一种常用的数据类型,但Struts2没有对该类型设置转换 ...

  7. SpringBoot在macOS下启动慢的原因

    title: SpringBoot在macOS下启动慢的原因 comments: false date: 2019-07-16 09:48:24 description: 在 macOS + JDk1 ...

  8. scipy.spatial.distance.cdist

    scipy.spatial.distance.cdist(XA, XB, metric='euclidean', p=2, V=None, VI=None, w=None)[source] Compu ...

  9. springmvc中的全注解模式

    1.贴在类上: @Controller表明其是一个控制器 2.贴在方法上: @requestMapping("/xxx"): 标明请求要访问的方法的资源路径,,需以/打头.其中省略 ...

  10. 剑指offer-5:十进制转二进制

    一.二进制中‘1’的个数 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. public class Solution { public int NumberOf1(int n) { ...