代码改变世界

命令模式

2019-03-05 17:22  剑动情缥缈  阅读(241)  评论(0编辑  收藏  举报

一.基本概念

  1.五种角色

  • 客户端(Client)角色:创建一个具体命令(ConcreteCommand)对象并确定其接收者。
  • 命令(Command)角色:声明了一个给所有具体命令类的抽象接口。
  • 具体命令(ConcreteCommand)角色:定义一个接收者和行为之间的弱耦合;实现execute()方法,负责调用接收者的相应操作。execute()方法通常叫做执行方法。
  • 请求者(Invoker)角色:负责调用命令对象执行请求,相关的方法叫做行动方法。
  • 接收者(Receiver)角色:负责具体实施和执行一个请求。任何一个类都可以成为接收者,实施和执行请求的方法叫做行动方法。

  2.请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。

  3.UML

  

二.代码

package com.chengjie;

import java.util.ArrayList;
import java.util.List;

//命令接收者:负责处理命令,如下buy()与sell()
class OrderReceiver {
    private String name = "ABC";
    private int quantity = 10;

    public void buy() {
        System.out.println("Stock [ Name: " + name + ", Quantity: " + quantity + " ] bought");
    }

    public void sell() {
        System.out.println("Stock [ Name: " + name + ", Quantity: " + quantity + " ] sold");
    }
}
//命令接口
interface Command {
    void execute();
}
//具体命令
class BuyOrder implements Command {
    public BuyOrder(OrderReceiver receiver) {
        this.receiver = receiver;
    }

    private OrderReceiver receiver;

    @Override
    public void execute() {
        receiver.buy();
    }
}
//具体命令
class SellOrder implements Command {
    private OrderReceiver receiver;

    public SellOrder(OrderReceiver receiver) {
        this.receiver = receiver;
    }

    public void execute() {
        receiver.sell();
    }
}
//请求者:负责调用命令执行具体请求
class Invoker {
    private List<Command> orderList = new ArrayList<Command>();

    public void addOrder(Command o) {
        orderList.add(o);
    }

    public void executeOrders() {
        for (Command o : orderList) {
            o.execute();
        }
        orderList.clear();
    }
}

public class TestCommandPattern {
    public static void main(String[] args) {
        //创建命令接收者
        OrderReceiver orderReceiver = new OrderReceiver();
        //创建具体命令对象,对将接收者注册进去
        BuyOrder buyOrder = new BuyOrder(orderReceiver);
        SellOrder sellOrder = new SellOrder(orderReceiver);
        //创建请求者
        Invoker invoker = new Invoker();
        //将命令注册进请求者
        invoker.addOrder(buyOrder);
        invoker.addOrder(sellOrder);
        //执行命令
        invoker.executeOrders();
    }
}
View Code

三.优点

  1.更松散的耦合:命令模式使得发起命令的对象——客户端,和具体实现命令的对象——接收者对象完全解耦,也就是说发起命令的对象完全不知道具体实现对象是谁,也不知道如何实现。

  2.更动态的控制:命令模式把请求封装起来,可以动态地对它进行参数化、队列化和日志化等操作,从而使得系统更灵活。

  3.很自然的复合命令:命令模式中的命令对象能够很容易地组合成复合命令,也就是宏命令,从而使系统操作更简单,功能更强大。

  4.更好的扩展性:由于发起命令的对象和具体的实现完全解耦,因此扩展新的命令就很容易,只需要实现新的命令对象,然后在装配的时候,把具体的实现对象设置到命令对象中,然后就可以使用这个命令对象,已有的实现完全不用变化

四.缺点

  1.使用命令模式可能会导致某些系统有过多的具体命令类

五.应用场景

  1.GUI的每一个按钮

  2.CMD

六.参考

  https://www.cnblogs.com/java-my-life/archive/2012/06/01/2526972.html

  http://www.runoob.com/design-pattern/command-pattern.html