• 「补课」进行时:设计模式(8)——命令模式


    1. 前文汇总

    「补课」进行时:设计模式系列

    2. 命令模式

    命令模式是一个高内聚的模式,其定义为:

    Encapsulate a request as anobject,thereby letting you parameterize clients with differentrequests,queue or log requests,and support undoable operations.(将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。)

    • Receive: 接收者角色,这个角色就是干活的角色,命令传递到这里是被执行的。
    • Command: 命令角色,需要执行的所有命令都在这里声明。
    • Invoker: 调用者角色,接收到命令,并执行命令。

    2.1 通用 Receiver 类

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

    这里使用抽象类的原因是接受者可以有多个,有多个就需要定义一个所有特性的抽象集合——抽象的接收者。

    2.2 具体的 Receiver 类

    public class ConcreteReceiver1 extends Receiver {
        @Override
        public void doSomething() {
    
        }
    }
    
    public class ConcreteReceiver2 extends Receiver {
        @Override
        public void doSomething() {
    
        }
    }
    

    每一个接受者都必须定义一定的业务逻辑。

    2.3 抽象的 Command 类

    public abstract class Command {
        public abstract void execute();
    }
    

    2.4 具体的 Command 类

    public class ConcreteCommand1 extends Command {
    
        private Receiver receiver;
    
        public ConcreteCommand1(Receiver receiver) {
            this.receiver = receiver;
        }
    
        @Override
        public void execute() {
            this.receiver.doSomething();
        }
    }
    
    public class ConcreteCommand2 extends Command {
    
        private Receiver receiver;
    
        public ConcreteCommand2(Receiver receiver) {
            this.receiver = receiver;
        }
    
        @Override
        public void execute() {
            this.receiver.doSomething();
        }
    }
    

    这里定义了两个具体的 Command 实现类,这里的每一个具体命令类,根据构造函数定义了具体是针对哪一个接受者发出的,同时定义了命令接收的主体。

    2.5 调用者 Invoker

    public class Invoker {
        private Command command;
    
        public void setCommand(Command command) {
            this.command = command;
        }
    
        public void action() {
            this.command.execute();
        }
    }
    

    调用者就是最终进行方法调用的地方,所有的命令都会由调用者进行调用。

    2.6 测试类

    public class Test {
        public static void main(String[] args) {
            Invoker invoker = new Invoker();
            // 定义接受者
            Receiver receiver = new ConcreteReceiver1();
            // 定义一个发送给接收者的命令
            Command command = new ConcreteCommand1(receiver);
            // 把命令交给调用者去执行
            invoker.setCommand(command);
            invoker.action();
        }
    }
    

    2.7 优点:

    • 类间解耦:调用者角色与接收者角色之间没有任何依赖关系,调用者实现功能时只需调用 Command 抽象类的 execute 方法就可以,不需要了解到底是哪个接收者执行。
    • 可扩展性: Command 的子类可以非常容易地扩展,而调用者 Invoker 和高层次的模块 Client 不产生严重的代码耦合。

    2.8 缺点:

    命令模式也是有缺点的,具体请注意 Command 的子类:如果有 N 个命令,问题就出来了, Command 的子类就可不是几个,而是 N 个,这个类膨胀得非常大,所以在使用命令模式的时候需要谨慎。

  • 相关阅读:
    【笔记】偏差方差权衡 Bias Variance Trade off
    【笔记】验证数据集与交叉验证
    【笔记】可视化模型误差之学习曲线
    【笔记】过拟合和欠拟合以及为什么要对分为训练数据集和测试数据集
    【笔记】多项式回归的思想以及在sklearn中使用多项式回归和pipeline
    【笔记】特征脸(PCA在人脸识别领域的应用)
    【笔记】使用PCA对数据进行降噪(理解)
    Kubernetes 中的 Pod 安全策略
    解读与部署(三):基于 Kubernetes 的微服务部署即代码
    【从小白到专家】Istio技术实践专题(四):应用接入Istio的正确姿势
  • 原文地址:https://www.cnblogs.com/babycomeon/p/13952210.html
Copyright © 2020-2023  润新知