Java设计模式--命令模式

1 Command Pattern 命令模式

目的:将请求发送者和接收者解耦,把一个请求封装成一个对象,通过不同的请求对象来执行不同的逻辑;
实现:通过调用者调用接受者执行命令,顺序:调用者→接受者→命令。

1.命令模式的核心在于引入了命令类,通过命令类来降低发送者和接收者的耦合度,请求发送者只需指定一个命令对象,再通过命令对象来调用请求接收者的处理方法;
2.命令模式的本质是对请求进行封装,一个请求对应于一个命令,将发出命令的责任和执行命令的责任分割开;
3.命令模式的关键在于引入了抽象命令类,请求发送者针对抽象命令类编程,只有实现了抽象命令类的具体命令才与请求接收者相关联。

2 实现

代码场景:秦昭襄王继位后,起用白起,他在咸阳发布命令,白起在东方诸国屡建战功,他们两个的协作可以看做是命令模式;
1. 秦昭襄王调用者角色
2. 白起接收者角色
3. 不同的命令具体命令类角色

2.1 代码实现

抽象命令类角色:Command类

public abstract class Command {

    // 执行命令
    public abstract void takeOrder();
}

具体命令类角色:虎符 HuFu类

public class HuFu extends Command {
    private BaiQi baiQi;

    public HuFu(BaiQi baiQi) {
        System.out.println("--具体命令角色--虎符--秦昭襄王將虎符交給白起");
        this.baiQi = baiQi;
    }

    @Override
    public void takeOrder() {
        baiQi.fight();
    }

}

具体命令类角色:自刎 Idioctonia类

public class Idioctonia extends Command {
    private BaiQi baiQi;
    public Idioctonia(BaiQi baiQi) {
        System.out.println("--具体命令角色--自刎--秦昭襄王派使者赐剑命白起自刎");
        this.baiQi = baiQi;
    }
    @Override
    public void takeOrder() {
        baiQi.ziWen();
    }
}

调用者角色:秦昭襄王 QinZhaoXiang类

public class QinZhaoXiang {
    private Command hufu;
    public void setHufu(Command hufu) {
        this.hufu = hufu;
    }
    //秦昭襄王
    public void makeDecision() {
        System.out.println("--调用者角色--秦昭襄王作出一個艰难的決定:");
        hufu.takeOrder();
    }
}

接收者角色:白起 BaiQi类

public class BaiQi {
    private List<String> deeds = new ArrayList<String>();
    private int index = 0;
    public BaiQi() {
        // 季君之乱
        deeds.add("--未使用命令模式--秦昭襄王立,白起助魏冉平季君之乱。");
        deeds.add("--接收者角色白起--秦昭襄王十四年,白起在崤函关以东灭韩魏联军二十四万人。");
        deeds.add("--接收者角色白起--秦昭襄王十五年,白起夺取魏大小六十一座城池。");
        deeds.add("--接收者角色白起--秦昭襄王二十八年,白起攻楚取五座城池。");
        deeds.add("--接收者角色白起--秦昭襄王二十九年,白起攻陷楚都城郢,楚王避难于陈。");
    }
    public void fight() {
        System.out.println(deeds.get(index));
        index++;
    }
    public void ziWen() {
        System.out.println("--接收者角色白起--秦昭襄王五十年,战神白起自刎于杜邮。");
    }
}

2.2 涉及角色

在命令模式结构图中包含如下几个角色:

Command(抽象命令类):抽象命令类一般是一个抽象类或接口,在其中声明了用于执行请求的 execute() 等方法,通过这些方法可以调用请求接收者的相关操作。

ConcreteCommand(具体命令类):具体命令类是抽象命令类的子类,实现了在抽象命令类中声明的方法,它对应具体的接收者对象,将接收者对象的动作绑定其中。在实现 execute() 方法时,将调用接收者对象的相关操作(Action)。

Invoker(调用者):调用者即请求发送者,它通过命令对象来执行请求。一个调用者并不需要在设计时确定其接收者,因此它只与抽象命令类之间存在关联关系。在程序运行时可以将一个具体命令对象注入其中,再调用具体命令对象的 execute() 方法,从而实现间接调用请求接收者的相关操作。

Receiver(接收者):接收者执行与请求相关的操作,它具体实现对请求的业务处理。

2.3 调用

调用者:

public class Client {
    public static void main(String[] args) {
        System.out.println("--秦武王于洛阳举鼎而死,秦昭襄王继位。");
        QinZhaoXiang zhaoXiangKing = new QinZhaoXiang();
        // 战神白起出现
        BaiQi baiQi = new BaiQi();
        // 不用命令模式的做法
        baiQi.fight();

        // 白起受到秦昭襄王重用
        System.out.println("------------打仗的命令---------------");
        Command huFu = new HuFu(baiQi);
        zhaoXiangKing.setHufu(huFu);

        zhaoXiangKing.makeDecision();
        zhaoXiangKing.makeDecision();
        zhaoXiangKing.makeDecision();

        // 秦昭襄王迁怒于白起
        System.out.println("------------命白起自刎的命令---------------");
        Idioctonia idioctonia = new Idioctonia(baiQi);
        zhaoXiangKing.setHufu(idioctonia);

        zhaoXiangKing.makeDecision();

    }
}

结果:

--秦武王于洛阳举鼎而死,秦昭襄王继位。
--未使用命令模式--秦昭襄王立,白起助魏冉平季君之乱。
------------打仗的命令---------------
--具体命令角色--虎符--秦昭襄王將虎符交給白起
--调用者角色--秦昭襄王作出一個艰难的決定:
--接收者角色白起--秦昭襄王十四年,白起在崤函关以东灭韩魏联军二十四万人。
--调用者角色--秦昭襄王作出一個艰难的決定:
--接收者角色白起--秦昭襄王十五年,白起夺取魏大小六十一座城池。
--调用者角色--秦昭襄王作出一個艰难的決定:
--接收者角色白起--秦昭襄王二十八年,白起攻楚取五座城池。
------------命白起自刎的命令---------------
--具体命令角色--自刎--秦昭襄王派使者赐剑命白起自刎
--调用者角色--秦昭襄王作出一個艰难的決定:
--接收者角色白起--秦昭襄王五十年,战神白起自刎于杜邮。

Java设计模式汇总:点击跳转
代码地址:点击跳转

参考文献:
[ 1 ] 图解设计模式/(日)结城浩著;杨文轩译。–北京:人民邮电出版社,2017.1.
[ 2 ] 维基百科 设计模式
[ 3 ] 极客学院WIKI–设计模式.
[ 4 ] 菜鸟教程–设计模式.

阅读更多
版权声明:本文为博主原创文章,欢迎转载。 https://blog.csdn.net/weixx3/article/details/80317511
个人分类: Design Patterns
所属专栏: Java 设计模式
上一篇Java设计模式--访问者模式
下一篇Java设计模式--解释器模式
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭