6月更文挑战|设计模式 —— 命令模式

这是我参与更文挑战的第11天,活动详情查看:更文挑战

命令模式

命令模式是行为型设计模式,它是将一系列指令封装,用户只需要调用接口就能完成一系列命令。比如电脑”关机“指令,对于用户可能只是一个关机操作,但对于电脑来说底层做了许多事情,暂停保存在执行的事件,保存系统配置,结束当前进程,最终内核命令真正关闭电脑。

定义:请求封装成对象,用户请求在客户端参数化,对请求排队或记录日志并支持可撤销操作。

实战

以下代码乍一看会觉得有点繁琐,一个功能类其实只要调用Paint就能实现所有功能,为什么还需要外层包装一层Command然后通过Button再调用?看似把简单的问题复杂化了。但设计模式上有必要把修改不提供对外,对外只提供扩展功能,对于调用者来说他只关心功能,不关心过程。命令模式并不是例子简单的将代码做层封装而已,其中也有它的特性所在,将paint的每个方法由每个Command进行包装是有目的的。当调用对应指令时可以记录对应执行了某个指令,当需要追溯历史时可以找到之前执行哪条指令从而使流程上支持可撤销功能。

所以在代码层次上看似乎直接可以调用Paint就能完成的工作,为什么还需要封装这么多类去完成是有道理和原因的。设计复杂的目的是为了让系统更健壮更具扩展性,并不是为了复杂而复杂。

public class Paint{
    public void drawLine(){}
    public void drawCircle(){}
    public void drawRectangle(){}
    public void fillColor(){}
}

public interface Command{
    void execute();
}

public class DrawLineCommand implements Command{
   Paint  paint;
   public DrawLineCommand(Paint paint){
       this.paint = paint;
   }
   @override
   void execute(){
       paint.drawLine();
   }
}
......
public class FillColorCommand implements Command{
   Paint  paint;
   public FillColorCommand(Paint paint){
       this.paint = paint;
   }
   @override
   void execute(){
       paint.fillColor();
   }
}

public class Button{
    private DrawLineCommand drawLineCommand;
    ......
    private FillColorCommand fillColorCommand;
    
    public void setDrawLineCommand(DrawLineCommand drawLineCommand){
        this.drawLineCommand = drawLineCommand;
    }
    ......
    public void setFillColorCommand(FillColorCommand fillColorCommand){
        this.fillColorCommand = fillColorCommand;
    }  
    public void drawLine(){
        drawLineCommand.drawLine();
    }
    ......
    public void fillColor(){
        fillColorCommand.fillColor();
    }
}

Button button = new Button();
button.drawLine();
button.fillColor();
复制代码

总结

命令模式缺点和大多数设计模式一样:类的膨胀。每新增一个功能可能就会衍生大量类的创建,但这也是不可避免的问题。但设计模式就是为了更好的弱耦合性,灵活控制性以及扩展性,牺牲一定类膨胀并不是致命的,比起代码可运行,后期代码可持久维护和可读性,还是有必要采用设计模式。不过实际开发中还是需要好好思考是否一定需要设计模式。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享