关注「Java视界」公众号,获取更多技术干货

命令模式Command —— 我不认识你,但我可以命令你

命令模式的核心在于引入了命令类,通过命令类来降低发送者和接收者的耦合度,请求发送者只需指定一个命令对象,再通过命令对象来调用请求接收者的处理方法。

一、什么是命令模式?

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

命令模式包含如下角色:

  • Receiver接收者角色
    命令接收者模式,命令传递到这里执行对应的操作。

  • Command命令角色
    需要执行的命令都在这里声明

  • Invoker调用者角色
    接收到命令,并执行命令,也就是命令的发动者和调用者

二、代码实现

抽象命令类:

public abstract class Command {

    public abstract void execute();
}

具体命令类:

@AllArgsConstructor
public class ConcreteCommand extends Command{

    private Receiver receiver;

    @Override
    public void execute() {
        receiver.action();
    }
}

调用者:

@AllArgsConstructor
public class Invoker {
    private Command command;

    public void call(){
        command.execute();
    }
}

抽象接收者:

public abstract class Receiver {
    public abstract void action();
}

具体接收者1:

public class ConcreteReceiver01 extends Receiver{

    @Override
    public void action() {
        Console.log("接收者【01】接到指令!开始行动!");
    }
}

具体接收者2:

public class ConcreteReceiver02 extends Receiver{

    @Override
    public void action() {
        Console.log("接收者【02】接到指令!开始行动!");
    }
}
public class Client {
    public static void main(String[] args) {
        ConcreteReceiver01 concreteReceiver01 = new ConcreteReceiver01();
        ConcreteCommand concreteCommand01 = new ConcreteCommand(concreteReceiver01);
        Invoker invoker01 = new Invoker(concreteCommand01);
        invoker01.call();

        ConcreteReceiver02 concreteReceiver02 = new ConcreteReceiver02();
        ConcreteCommand concreteCommand02 = new ConcreteCommand(concreteReceiver02);
        Invoker invoker02 = new Invoker(concreteCommand02);
        invoker02.call();
    }
}
接收者【01】接到指令!开始行动!
接收者【02】接到指令!开始行动!

三、适用场景

优点:

  • 类间解耦
    • 调用者和接受者之间没有任何依赖关系
    • 调用者实现的时候只需要调用Command抽象类的execute方法就行了
    • 不需要了解到底是谁在执行
  • 可扩展性
    • Command的子类非常容易扩展,调用者Invoker和高层次的Client不产生严重的代码耦合
  • 命令模式结合其他模式会更优秀
    • 命令模式可以结合责任链模式,实现命令族解析任务
    • 结合模板方法模式,则可以减少Command子类的膨胀问题。

缺点:

  • 如果有N个命令,就需要N个Command的子类,类膨胀非常大

适用场景:

​ 在某些场合,比如要对行为进行"记录、撤销/重做、事务"等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将"行为请求者"与"行为实现者"解耦?将一组行为抽象为对象,可以实现二者之间的松耦合。

只要你认为是命令的地方就可以采用命令模式,例如,在GUI开发中,一个按钮的点击是一个命令,可以采用命令模式;模拟DOS命令的时候,当然也要采用命令模式;触发-反馈机制的处理等。 

posted @ 2022-06-25 14:02  沙滩de流沙  阅读(71)  评论(0编辑  收藏  举报

关注「Java视界」公众号,获取更多技术干货