软件设计模式—命令模式

前篇——软件设计模式-基础
前篇——软件设计模式-三种工厂模式
前篇——软件设计模式-装饰者模式
前篇——软件设计模式-单例模式
前篇——软件设计模式-原型模式

命令模式是对象行为型模式

1. 问题引入

用遥控器来实现家电的开关

1.1 e.g.1(灯开关)

//灯
public class LightTwo{
    public void onLighht(){
        System.out.println("Light is on");
    }
    public void offLighht(){
        System.out.println("Light is off");
    }
}
//遥控器
public class ControlBarTwo{
    public LightTwo light;
    public ControlBarTwo(LightTwo light){
        this.light = light;
    }
    public void on(){
        light.onLighht();
    }
    public void off(){
        light.offLighht();
    }
}
//测试类
public class Test{
    public static void main(String[] args) {
        LightTwo light = new LightTwo();
        ControlBarTwo bar = new ControlBarTwo(light);
        bar.on();
        bar.off();
    }
}

1.2 耦合度过高的问题

虽然实现了功能,但是遥控器和灯耦合性太高。可通过命令模式来解耦。

2.命令模式

2.1 定义

定义:将一个请求封装成一个对象,从而可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作

2.1.1 定义理解

理解:一个请求封装为一个对象,将发出请求和执行请求分割开。然后请求和执行通过命令对象来进行沟通。
再通俗一点,A对象请求B对象,调用B对象的方法,来完成功能的模式

2.1.2 类图

在这里插入图片描述

2.2 e.g.2 命令模式实现e.g.1并扩展一个电扇

在这里插入图片描述

//抽象命令
public interface HomeCommand{
    public void execute();
}
//开命令
public class OpenCommand implements HomeCommand{
    private ElectricAppliance ea;
    public void execute(){
        ea.openThat();
    }
    public OpenCommand(ElectricAppliance ea){
        this.ea = ea;
    }
}
//关命令
public class CloseCommand implements HomeCommand{
    private ElectricAppliance ea;
    public void execute(){
        ea.closeThat();
    }
    public CloseCommand(ElectricAppliance ea){
        this.ea = ea;
    }
}
//抽象接收者
public abstract class ElectricAppliance{
    public abstract void openThat();
    public abstract void closeThat();
}
//具体接收者——电风扇
public class Fan extends ElectricAppliance{
    public void openThat(){
        System.out.println("Fan is opening");
    }
    public void closeThat(){
        System.out.println("Fan is closed");
    }
}
//具体接收者——灯
public class Light extends ElectricAppliance{
    public void openThat(){
        System.out.println("Light is opening");
    }
    public void closeThat(){
        System.out.println("Light is closed");
    }
}
//请求者——遥控器
public class SuperBar{
    HomeCommand command;
    public SuperBar(HomeCommand command){
        this.command = command;
    }
    public void pressDown(){
        command.execute();
    }
}
//测试类
public class Test{
    public static void main(String[] args){
    	//创建一个电扇1
        ElectricAppliance fan1 = new Fan();
        //创建一个开电扇的命令对象
        HomeCommand command_fan_open = new OpenCommand(fan1);
        //创建一个第一次请求的请求对象
        SuperBar bar_fan_1st = new SuperBar(command_fan_open);
        System.out.println("Siri帮我开电扇");
        bar_fan_1st.pressDown();
        //同理
        HomeCommand command_fan_close = new CloseCommand(fan1);
        SuperBar bar_fan_2nd = new SuperBar(command_fan_close);
        System.out.println("Siri帮我关电扇");
        bar_fan_2nd.pressDown();
    }
}

2.3 结构(组成角色)

四种角色(结合e.g.2的结构举例):

  1. 抽象命令类(HomeCommand):声明执行命令的接口,拥有执行命令的抽象方法execute()。
  2. 具体命令(CloseCommandOpenCommand):是抽象命令类的具体实现类,他拥有接受者对象,并通过调用接收者的功能来完成命令要执行的操作。
  3. 接收者(FanLight):是一个类的实例,该实例负责执行与请求相关的操作是具体命令对象业务的真正实现者。
  4. 请求者(SuperBar):是请求的发送者,是一个包含Command接口变量的类的实例。请求者中的Command接口的变量,可以存放任何具体命令的引用。请求者负责调用具体命令,让具体命令执行哪些封装的“请求”的方法。他不直接访问接收者。

3.命令模式的特点(使用场景、优缺点)

看到一句话:当需要先将一个函数登记上,然后再以在以后调用此函数,此时我们就需要使用命令模式。
其实这也就是回调函数。

3.1 使用场景

  1. 概念:需要向A对象 发送个请求,但不知道接收者 、不知道请求的操作。此时我们用一种松耦合方式来设计程序,使得请求发送者和请求接收者消除彼此之间的耦合关系。
  2. 举个栗子:你去吃饭,向厨师发生请求——帮我做一道菜(请求),你不知道厨师的名字和联系方式(不知道接收者),也不知道厨师是怎么做的(不知道请求的操作)。 此时我们使用命令模式是怎么解决的呢。命令模式把客人的请求封装成Command对象(即订餐中的订单对象)。这个对象可以被服务员交给厨师、经理(对象在程序之间被四处传递)。到厨师手里,处理请求。你在订餐的过程中,见不到厨师、了解不到的厨师的信息并且请求可以被完成(从而解开了请求调用者和请求接收者之间的耦合关系)。

3.2 命令模式的优缺点

3.2.1 优点

  1. 类间解耦:如3.1中栗子所表现的那样
  2. 可扩展性:Command的子类可以非常容易的扩展,而调用者Invoker和高层次测试类不产生严重的代码耦合。
  3. 命令模式结合其他模式会更加优秀:在扩展电扇类(Fan)的时候,你应该能察觉,完全可以结合之前的一些模式,让命令模式 的 缺点轻松解决。

3.2.2 缺点

你看Command的子类,如果命令过多,问题就来了,Command的子类是N个,这个类会膨胀的非常大。
在e.g.2中,如果之间扩展电扇的话,我们应该会有4个具体命令(开电扇、关电扇、开灯、关灯),而实际上我们结合了一点工厂模式,将灯、电扇抽象为家具类。依旧通过两个具体命令实现了功能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值