zoukankan      html  css  js  c++  java
  • 命令模式-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

  • 相关阅读:
    ASP.NET MVC 学习: 视图
    翻译:ASP.NET MVC Example Application over Northwind with Entity Framework
    主流web2.0网站的配色参考方案
    jQuery1.2选择器
    ASP.NET MVC URL Routing 学习
    [转]关于DOM元素定位属性的深入学习
    ASP.NET MVC : Action过滤器(Filtering)
    【翻译】使用ASP.NET MVC 和LINQ建立一个简单的博客 Part 3
    Windows 8开发者训练营第一日来自现场的图片报道
    从数据到信息到决策
  • 原文地址:https://www.cnblogs.com/rouqinglangzi/p/11386062.html
Copyright © 2011-2022 走看看