命令模式-Command Pattern

命令模式是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。

一、类图

经典的命令模式包括如下4个角色:

  • Command:定义命令的统一接口
  • ConcreteCommand:Command接口的实现者,用来执行具体的命令,某些情况下可以直接用来充当Receiver。
  • Receiver:命令的实际执行者
  • Invoker:命令的请求者,是命令模式中最重要的角色。这个角色用来对各个命令进行控制。

二、示例

电视机是请求的接收者,遥控器是请求的发送者,遥控器上有一些按钮,不同的按钮对应电视机的不同操作。抽象命令角色由一个命令接口来扮演,有三个具体的命令类实现了抽象命令接口,这三个具体命令类分别代表三种操作:打开电视机、关闭电视机和切换频道。显然,电视机遥控器就是一个典型的命令模式应用实例。
抽象命令类:

public interface AbstractCommand{
    public void execute();
}

具体的命令类:换台

public class TVChangeCommand implements AbstractCommand{

    private Television tv;

    public TVChangeCommand(){
        tv = new Television();
    }

    public void execute(){
        tv.changeChannel();
    }

}

具体的命令类:关机

public class TVCloseCommand implements AbstractCommand{

    private Television tv;

    public TVCloseCommand(){
        tv = new Television();
    }

    public void execute(){
        tv.close();
    }

}

具体的命令类:开机

public class TVOpenCommand implements AbstractCommand{
    
        private Television tv;
    
        public TVOpenCommand(){
        tv = new Television();
    }

    public void execute(){
        tv.open();
    }

}

接收者类

public class Television{
    
        public void open(){
        System.out.println("打开电视机!");
    }
    
    public void close()
    {
        System.out.println("关闭电视机!");        
    }
    
    public void changeChannel()
    {
        System.out.println("切换电视频道!");
    }

}

调用者(Invoker)类

public class Controller {
    private AbstractCommand openCommand, closeCommand, changeCommand;

    public Controller(AbstractCommand openCommand, AbstractCommand closeCommand, AbstractCommand changeCommand) {
        this.openCommand = openCommand;
        this.closeCommand = closeCommand;
        this.changeCommand = changeCommand;
    }

    public void open() {
        openCommand.execute();
    }

    public void change() {
        changeCommand.execute();
    }

    public void close() {
        closeCommand.execute();
    }
}

三、优缺点

优点

每个命令都被封装起来,对于客户端来说,需要什么功能就去调用相应的命令,而无需知道命令具体是怎么执行的。比如有一组文件操作的命令:新建文件、复制文件、删除文件。如果把这三个操作都封装成一个命令类,客户端只需要知道有这三个命令类即可,至于命令类中封装好的逻辑,客户端则无需知道。

其次,命令模式的扩展性很好,在命令模式中,在接收者类中一般会对操作进行最基本的封装,命令类则通过对这些基本的操作进行二次封装,当增加新命令的时候,对命令类的编写一般不是从零开始的,有大量的接收者类可供调用,也有大量的命令类可供调用,代码的复用性很好。比如,文件的操作中,我们需要增加一个剪切文件的命令,则只需要把复制文件和删除文件这两个命令组合一下就行了,非常方便。

缺点

命令模式的缺点就是命令如果很多,开发起来就要头疼了。特别是很多简单的命令,实现起来就几行代码的事,而使用命令模式的话,不用管命令多简单,都需要写一个命令类来封装。

四、Tomcat中命令模式

Tomcat中Connector 也是通过命令模式调用 Container。Connector 作为抽象请求者,HttpConnector 作为具体请求者。HttpProcessor 作为命令。Container 作为命令的抽象接受者,ContainerBase 作为具体的接受者。客户端就是应用服务器 Server 组件了。Server 首先创建命令请求者 HttpConnector 对象,然后创建命令 HttpProcessor 命令对象。再把命令对象交给命令接受者 ContainerBase 容器来处理命令。命令的最终是被 Tomcat 的 Container 执行的。命令可以以队列的方式进来,Container 也可以以不同的方式来处理请求,如 HTTP1.0 协议和 HTTP1.1 的处理方式就会不同。

 

……更多设计模式的内容,可以访问Refactoring.Guru

posted @ 2019-10-29 20:27  静水楼台/Java部落阁  阅读(241)  评论(0编辑  收藏  举报