zoukankan      html  css  js  c++  java
  • 设计模式-命令模式(16)

    定义

    命令模式(Command Pattern)又称为行动(Action)模式或者交易(Transaction)模式。

    英文原话:Encapsulate a request as an object,thereby letting you parameterize clients with different requests,queue or log requests,and support undoable operations.

    翻译:将一个请求封装成一个对象,从而让你能使用不同的请求把客户端参数化,对于请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。

    角色:

    命令(Command)角色:该角色声明一个给所有具体命令类的抽象接口,定义需要执行的命令。

    具体命令(Concrete Command)角色:该角色定义一个接收者和行为之间的弱耦合,实现命令方法,并调用接受者的相应操作。

    调用者(Invoker)角色:该角色负责调用命令对象的执行请求。

    接收者(Receive)角色:该角色负责具体实施和执行一个请求。

    /**
     * 命令接口
     */
    public interface Command {
        //执行命令方法
        public void execute();
    }
    
    /**
     * 具体命令角色
     */
    public class ConcreteCommand implements Command {
        private Receiver receiver;
    
        public ConcreteCommand(Receiver receiver) {
            this.receiver = receiver;
        }
    
        @Override
        public void execute() {
            this.receiver.action();
        }
    }
    
    /**
     * 接收者
     */
    public class Receiver {
        //行动方法
        public void action(){
            System.out.println("执行动作");
        }
    }
    
    /**
     * 调用者
     */
    public class Invoker {
        private Command command;
        //接收命令
        public void setCommand(Command command){
            this.command = command;
        }
        //执行命令
        public void action(){
            this.command.execute();
        }
    }
    
    /**
     * 测试类
     */
    public class Client {
        public static void main(String[] args) {
            //调用者
            Invoker invoker = new Invoker();
            //接收者
            Receiver receiver = new Receiver();
            //定义一个发送给接收者的命令
            Command command = new ConcreteCommand(receiver);
            //执行
            invoker.setCommand(command);
            invoker.action();
        }
    }

    源码

    优点

    • 类间解耦。调用者角色与接收者角色之间没有任何依赖关系,调用者实现功能时只需调用Command中的execute()方法即可,不需要了解是哪个接收者来执行。
    • 可扩展性。Command的子类非常容易扩展,而调用者Invoker和高层次的模块Client不产生严重的代码耦合。
    • 命令模式结合其他模式会更优秀。命令模式可以结合责任链模式,实现命令族解析任务;结合模板方法模式,可以减少Command子类的膨胀。

    缺点

    使用命令模式可能会导致系统中出现过多的具体命令类,因此在项目中使用命令模式时需要慎重考虑。

    应用场景

    • 使用命令模式作为“回调”在面向对象系统中的代替。“回调”就是将一个函数登记,方便在以后调用此函数。
    • 需要在不同的时间指定请求、将请求排队。
    • 系统需要支持命令的撤销(undo)。命令对象可以把状态存储起来,等到客户端需要撤销时,可以调用undo()方法,将命令所产生的效果撤销。
    • 需要将系统中所有的数据更新操作保存到日志里,以便在系统崩溃时,可以根据日志读回所有的数据更新命令,重新调用execute()方法,一条一条执行这些命令,从而恢复系统在崩溃前所做的数据更新。
    • 一个系统需要支持交易(transaction)。一个交易结构封装了一组数据更新命令。使用命令模式来实现交易结构可以使系统增加新的交易类型。
    /**
     * 命令接收者
     */
    public class Receiver {
        public void turnON(){
            System.out.println("开灯~~~");
        }
    
        public void turnOFF(){
            System.out.println("熄灯~~~");
        }
    }
    
    /**
     * 命令接口
     */
    public interface Command {
    
        public void execute();
    }
    
    /**
     * 开灯命令
     */
    public class LightOnCommand implements Command{
        private Receiver receiver;
    
        public LightOnCommand(Receiver receiver) {
            this.receiver = receiver;
        }
    
        @Override
        public void execute() {
            this.receiver.turnON();
        }
    }
    
    /**
     * 关灯命令
     */
    public class LightOffCommand implements Command{
        private Receiver receiver;
    
        public LightOffCommand(Receiver receiver) {
            this.receiver = receiver;
        }
    
    
        @Override
        public void execute() {
            receiver.turnOFF();
        }
    }
    
    /**
     * 调用者
     */
    public class Invoker {
        public void invoker(Command command){
            command.execute();    //执行命令
        }
    }
    
    /**
     * 测试类
     */
    public class Main {
        public static void main(String[] args) {
            Receiver receiver = new Receiver();    //接收者
            Command command1 = new LightOnCommand(receiver);    //开灯命令
            Command command2 = new LightOffCommand(receiver);    //开灯命令
            Invoker invoker = new Invoker();
            invoker.invoker(command1);
            invoker.invoker(command2);
        }
    }

    源码

  • 相关阅读:
    Analysis Services features supported by SQL Server editions
    Azure DevOps to Azure AppServices
    Power BI For Competition
    Win10开机“提示语音”以及”随机播放音乐”
    Azure DevOps
    Allow Only Ajax Requests For An Action In ASP.NET Core
    Mobile CI/CD 101
    Configure SSL for SharePoint 2013
    AWS Step Function Serverless Applications
    Cordova Upload Images using File Transfer Plugin and .Net core WebAPI
  • 原文地址:https://www.cnblogs.com/aeolian/p/8881368.html
Copyright © 2011-2022 走看看