美文网首页设计模式我爱编程
【设计模式笔记】(九)- 命令模式

【设计模式笔记】(九)- 命令模式

作者: MrTrying | 来源:发表于2018-04-14 14:36 被阅读53次

    1.简述

    命令模式(Command Pattern),将一个请求封装为一个对象或者操作封装到一个对象中,从而使用户可用不同的请求把客户参数化;对请求排队或记录请求日志,以及支持可撤销的操作。

    命令模式.png

    UML图中

    • Client:客户端,也就是发出命令者
    • Invoker:执行者,该类的职责就是调用命令对象执行具体的请求,相关的方法我们称为行动方法
    • Command:命令,定义所有具体命令类的抽象接口
    • ConcreteCommand:具体命令,实现了Command接口,在execute()方法中调用Receiver相关的方法
    • Receiver:接收者,负责执行具体逻辑

    整体来看,命令模式比较繁琐,执行一个指令的过程被分解成了好几部分,相对的复杂度也提升了;但是命令模式结构还是很清晰的。

    2.实现

    记得有个段子:

    如果有一个按钮,按下以后会忘记一切事情,你会怎样?
    咦,这里有个按钮,按一下
    咦,这里有个按钮,按一下
    咦,这里有个按钮,按一下
    。。。

    其实这个按下这个按钮就是执行了一个命令,是一个让你忘记一切的命令(于是自己开始递归,最后还Stack Overflow了?)。

    首先,我们需要一个接收者Receiver,来实现我们所传递的命令

    public class Receiver {
        public void action(){
            //具体命令操作
            System.out.println("清除所有记忆");
        }
    }
    

    这里接收者只执行这一个命令,复杂的情况们可以继承Receiver来实现不同的接收者处理不同的命令。

    再是一个命令的接口Command和一个具体的Command实现类CleanMemoryCommand,很简单,只有一个没有实现的execute()方法

    /** 命令接口 */
    public interface Command {
        public void execute();
    }
    
    /** 清除记忆命令 */
    public class CleanMemoryCommand implements Command {
    
        Receiver receiver;
    
        public CleanMemoryCommand(Receiver receiver){
            this.receiver = receiver;
        }
    
        @Override
        public void execute() {
            receiver.action();
        }
    }
    

    这样,命令和接收者都有了,我们只差一个供用户直接使用的Invoker

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

    调用的代码就比较简单了,这代码可以封装成一个方法

    public class Client {
        public static void main(String[] args){
            Receiver receiver = new Receiver();
            CleanMemoryCommand command = new CleanMemoryCommand(receiver);
            Invoker invoker = new Invoker(command);
            invoker.actoin();
        }
    }
    

    3.总结

    命令模式看似简单,细想来其实存在着几乎所有设计模式的通病,那就是大量衍生类的创建,这是一个不可避免的问题。

    尽管如此,也给我们带来了许多好处,更弱的耦合性、更灵活的控制性以及更好的扩展性。但是最后还是那句话,用不用,还是根据实际情况而定。

    「推荐」设计模式系列

    设计模式(零)- 面向对象的六大原则
    设计模式(一)- 单例模式
    设计模式(二)- Builder模式
    设计模式(三)- 原型模式
    设计模式(四)- 工厂模式
    设计模式(五)- 策略模式
    设计模式(六)- 状态模式
    设计模式(七)- 责任链模式
    设计模式(八)- 解释器模式
    设计模式(九)- 命令模式
    设计模式(十)- 观察者模式
    设计模式(十一)- 备忘录模式
    设计模式(十二)- 迭代器模式
    设计模式(十三)- 模板方法模式
    设计模式(十四)- 访问者模式
    设计模式(十五)- 中介者模式
    设计模式(十六)- 代理模式
    设计模式(十七)- 组合模式
    【设计模式笔记】(十八)- 适配器模式
    【设计模式笔记】(十九)- 装饰者模式

    本文内容基于《Android源码设计模式解析与实践》

    相关文章

      网友评论

        本文标题:【设计模式笔记】(九)- 命令模式

        本文链接:https://www.haomeiwen.com/subject/forlkftx.html