zoukankan      html  css  js  c++  java
  • 设计模式之命令模式学习理解

    命令模式

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

    介绍

    意图:将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化。

    主要解决:在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录、撤销或重做、事务等处理时,这种无法抵御变化的紧耦合的设计就不太合适。

    何时使用:在某些场合,比如要对行为进行"记录、撤销/重做、事务"等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将"行为请求者"与"行为实现者"解耦?将一组行为抽象为对象,可以实现二者之间的松耦合。

    如何解决:通过调用者调用接受者执行命令,顺序:调用者→接受者→命令。

    关键代码:定义三个角色:1、received 真正的命令执行对象 2、Command 3、invoker 使用命令对象的入口

    应用实例:struts 1 中的 action 核心控制器 ActionServlet 只有一个,相当于 Invoker,而模型层的类会随着不同的应用有不同的模型类,相当于具体的 Command。

    优点: 1、降低了系统耦合度。 2、新的命令可以很容易添加到系统中去。

    缺点:使用命令模式可能会导致某些系统有过多的具体命令类。

    使用场景:认为是命令的地方都可以使用命令模式,比如: 1、GUI 中每一个按钮都是一条命令。 2、模拟 CMD。

    注意事项:系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作,也可以考虑使用命令模式,见命令模式的扩展。

    假设现在有个创建工单的类,还有个安装工的类负责接收和安装工单。

    简单的紧耦合实现

     1 /**
     2  * 新建工单类
     3  * @author ko
     4  *
     5  */
     6 public class NewlyBuildOrder {
     7 
     8     public void buildTypeAOrder(){
     9         System.out.println("build type a order...");
    10     }
    11     
    12     public void buildTypeBOrder(){
    13         System.out.println("build type b order...");
    14     }
    15     
    16 }
     1 /**
     2  * 安装工
     3  * 接单并安装
     4  * @author ko
     5  *
     6  */
     7 public class Installer {
     8     
     9     public void receiveInstall(NewlyBuildOrder newlyBuildOrder){
    10         
    11         newlyBuildOrder.buildTypeAOrder();
    12         newlyBuildOrder.buildTypeBOrder();
    13         newlyBuildOrder.buildTypeAOrder();
    14         newlyBuildOrder.buildTypeAOrder();
    15         
    16     }
    17     
    18 }
     1 /**
     2  * 测试类
     3  * 新建工单
     4  * 安装工领取并安装工单
     5  * @author ko
     6  *
     7  */
     8 public class Test {
     9 
    10     public static void main(String[] args) {
    11         NewlyBuildOrder newlyBuildOrder = new NewlyBuildOrder();
    12         Installer installer = new Installer();
    13         installer.receiveInstall(newlyBuildOrder);
    14     }
    15 }
    build type a order...
    build type b order...
    build type a order...
    build type a order...
    

    这其实是行为请求者和行为实现者的紧耦合,这样写有很多弊端,如果安装工多了,那就会很混乱,没有日志记录,另外需要撤销领取的工单重新领取也不行。

    松耦合命令模式实现

     1 // 把行为请求者对行为实现者的命令抽象成类
     2 public abstract class Command {
     3 
     4     protected NewlyBuildOrder newlyBuildOrder;
     5 
     6     public Command(NewlyBuildOrder newlyBuildOrder){
     7         this.newlyBuildOrder = newlyBuildOrder;
     8     }
     9     
    10     // 执行命令
    11     public abstract void excuteCommand();
    12     
    13 }
     1 // A类工单命令
     2 public class TypeAOrderCommand extends Command {
     3 
     4     public TypeAOrderCommand(NewlyBuildOrder newlyBuildOrder) {
     5         super(newlyBuildOrder);
     6         // TODO Auto-generated constructor stub
     7     }
     8 
     9     @Override
    10     public void excuteCommand() {
    11         newlyBuildOrder.buildTypeAOrder();
    12     }
    13 
    14     @Override
    15     public String toString() {
    16         return "TypeAOrderCommand";
    17     }
    18 
    19 }
     1 // B类工单命令
     2 public class TypeBOrderCommand extends Command {
     3 
     4     public TypeBOrderCommand(NewlyBuildOrder newlyBuildOrder) {
     5         super(newlyBuildOrder);
     6         // TODO Auto-generated constructor stub
     7     }
     8 
     9     @Override
    10     public void excuteCommand() {
    11         newlyBuildOrder.buildTypeBOrder();
    12     }
    13 
    14     @Override
    15     public String toString() {
    16         return "TypeBOrderCommand";
    17     }
    18 
    19 }
     1 /**
     2  * 工单管理
     3  * 介于行为请求者和行为实现者之间的类
     4  * @author ko
     5  *
     6  */
     7 public class OrderManage {
     8 
     9     private List<Command> orders = new ArrayList<>();// 存放具体命令的容器
    10     
    11     // 设置订单
    12     // 对于工单管理类,不管安装工想要的是什么类型的工单,反正都是‘命令’,只管记录订单,
    13     // 
    14     public void setOrder(Command command){
    15         if (command.toString().equals("TypeAOrderCommand")) {
    16             System.out.println("type a order is over, can't provide ...");
    17         }else{
    18             orders.add(command);
    19             // 打印日志
    20             System.out.println("LOG   add order:"+command.toString()+",time:"+System.currentTimeMillis());
    21         }
    22     }
    23     
    24     // 撤销订单
    25     public void revokeOrder(Command command){
    26         orders.remove(command);
    27         // 打印日志
    28         System.out.println("LOG   revoke order:"+command.toString()+",time:"+System.currentTimeMillis());
    29     }
    30     
    31     public void notifyBuilder(){
    32         for (Command command : orders) {
    33             command.excuteCommand();
    34         }
    35     }
    36     
    37 }
     1 /**
     2  * 新建工单类
     3  * @author ko
     4  *
     5  */
     6 public class NewlyBuildOrder {
     7 
     8     public void buildTypeAOrder(){
     9         System.out.println("build type a order...");
    10     }
    11     
    12     public void buildTypeBOrder(){
    13         System.out.println("build type b order...");
    14     }
    15     
    16 }
     1 /**
     2  * 测试类
     3  * @author ko
     4  *
     5  */
     6 public class Test {
     7 
     8     public static void main(String[] args) {
     9         // 初始准备
    10         NewlyBuildOrder newlyBuildOrder = new NewlyBuildOrder();
    11         Command typeAOrderCommand = new TypeAOrderCommand(newlyBuildOrder);
    12         Command typeBOrderCommand = new TypeBOrderCommand(newlyBuildOrder);
    13         OrderManage orderManage = new OrderManage();
    14 
    15         // 设置命令
    16         orderManage.setOrder(typeAOrderCommand);
    17         orderManage.setOrder(typeBOrderCommand);
    18         
    19         // 通知order builder
    20         orderManage.notifyBuilder();
    21         
    22     }
    23 }
    type a order is over, can't provide ...
    LOG   add order:TypeBOrderCommand,time:1500879972241
    build type b order...
    

      

  • 相关阅读:
    Bundle Adjustment
    BFL ekf imu and odom
    RNN
    深度学习的数学(笔记)
    BP 神经网络
    PCA
    SVM
    KNN
    Kmeans
    决策树
  • 原文地址:https://www.cnblogs.com/shamo89/p/7229071.html
Copyright © 2011-2022 走看看