设计模式之行为模式(一)

版权声明:欢迎转载评论~哈哈哈哈请标明出处呀 https://blog.csdn.net/legendaryhaha/article/details/89225103

命令模式


命令模式:将请求封住成对象,通过对象来实现对请求的控制(排队、顺序执行和取消)

模式无非就是让模块间能够解耦,让程序的复用性更强,命令模式也不例外,它是解决代表客户发送请求的调用者和提供服务的接受者之间的耦合关系的。


譬如:我们去一家餐厅吃放,我们点菜,服务员将菜单传递给厨师,这个流程中,我们相当于客户端client,点菜相当于发送请求,服务员相当于调用者invoke,根据请求调用相应的厨师(假设厨师有多个,每个厨师有自己的拿手好菜,所以我们点的菜可能由多位厨师进行实现),而厨师就是接受者receiver。

那么问题来了,在用程序描述invoke时,我们可能出现这种情况:

if("请求类型type"==A)
    "调用厨师A"
 if("请求类型type"==B)
    "调用厨师B"
 if("请求类型type"==C)
    "调用厨师C"   

如果有100位厨师,那么你可能就写100条if语句了(或者其他一些逻辑判断),然后你的同事可能就提着菜刀在赶来的路上了。
在这里插入图片描述
在这种有多个命令的情况下,为了对命令进行统一的管理,并对invoke和receiver进行解耦,行为模式中建议用命令模式进行程序设计。


命令模式涉及到的角色:

  • 抽象命令接口Command:定义命令的接口,声明执行的方法。(点菜动作)
  • 具体的命令对象ConcreteCommand:持有具体的接受者对象,完成具体的具体的命令。(点哪些菜)
  • 接受者对象Receiver:接受者对象,真正执行命令的对象。(厨师)
  • 传递命令对象Invoker:持有命令对象,要求命令对象执行请求。(服务员)
  • 客户端对象Client:创建具体命令的对象并且设置命令对象的接受者。

解耦后
在这里插入图片描述

public interface AbstractCommandOrder {
    //定义抽象的点菜命令接口,定义抽象的执行动作
    void execute();
}
public class ConcreteCommandOrder implements AbstractCommandOrder {
/**
 * 定义具体的点菜命令,持有接受者
 */
    private CookReceiver cookReceiver;

    public ConcreteCommandOrder(CookReceiver receiver){
        cookReceiver = receiver;
    }
@Override
    public void execute() {
        cookReceiver.cookAcion();
    }
}
public class WaiterInvoker {
/**
  服务员调用者
*/
    private AbstractCommandOrder commandOrder;

    public WaiterInvoker(){ }

    public WaiterInvoker(AbstractCommandOrder command){
        commandOrder = command;
    }

    public void waiterAction(){
        System.out.println("服务员:已接收菜单->将菜单转交给厨师");
        commandOrder.execute();
    }
}
public class CookReceiver {
   /**
     厨师接受者
   */
    private String name;

    public CookReceiver(String name){
        this.name = name;
    }
    public void cookAcion(){
        System.out.println("厨师:做"+name);
    }
}
public class Client {
   /**
     模拟客户端
   */
    public static void main(String[] args) {
    
        System.out.println("我想要一份丢丢辣的开心花甲粉");
        /**
          封装命令
        */
        AbstractCommandOrder command = new ConcreteCommandOrder(new CookReceiver("花甲粉"));
        WaiterInvoker waiterInvoker = new WaiterInvoker(command);
        waiterInvoker.waiterAction();
    }
}

小结

上面的代码是我参考Java软件体系结构和设计模式一书和其他一些博主后写的,也是很常见的写法。但个人认为还可以进一步解耦,正如我们前面说的,厨师可能有多为,西餐厨师,中餐厨师,即我们可以进一步对厨师进行抽象,使命令封装模块command依赖于抽象而不是细节,不过说来说去,还是得看具体需要,某些例子可能只能作为理解模式的参考,但实际应用中,切勿生搬硬套。

猜你喜欢

转载自blog.csdn.net/legendaryhaha/article/details/89225103