Gof-命令模式

继续打卡设计模式

今天来聊一下的是命令模式

命令模式使得请求发送者与请求接受者消除彼此之间的耦合

一、实际问题

我们现在有一套只能家居,有照明灯、风扇、电视等等 我们现在需要在手机上安装一个app就可以控制这些家电的工作。
这些智能家电来自不同的厂家,我们不需要针对每一个家电都安装一个APP。分别控制。我们希望只要一个APP就可以控制全部智能家电。

针对这个问题我们先分析一下,我们肯定不会每一个家电都单独安装一个APP,那就是想用一个APP来控制这些所有家电,我们是不是需要对这个APP提供一个对外的接口来方便这些智能家电来调用呢。

二、命令模式来实现

直接用程序模拟可能更加直观,我们第一步就是需要有这些一个个智能家电个体

/**
 * @author: 德鑫
 * Description:
 * @Date: 2021/01/27
 */

public class TVReceiver {
    public void on() {
        System.out.println(" 电视机打开了.. ");
    }

    public void off() {
        System.out.println(" 电视机关闭了.. ");
    }
}
/**
 * @author: 德鑫
 * Description:
 * @Date: 2021/01/27
 */

public class LightReceiver {

    public void on() {
        System.out.println(" 电灯打开了.. ");
    }

    public void off() {
        System.out.println(" 电灯关闭了.. ");
    }

}

现在两套智能家电也已经具备了我们需要的就是针对这两套智能家电来进行便捷的控制,手机APP就好比是我们的客户端,最后测试我们就是针对客户端来调用这些智能家电。
那现在我们就需要来提供一个统一的接口了

/**
 * @author: 德鑫
 * Description:
 * @Date: 2021/01/27
 */
//创建命令接口
public interface Command {
        //执行
    public void execute();
        //撤销
    public void undo();

}
/**
 * @author: 德鑫
 * Description:
 * @Date: 2021/01/27
 */

public class TVOffCommand implements Command {

    // 聚合TVReceiver
    TVReceiver tv;

    // 构造器
    public TVOffCommand(TVReceiver tv) {
        super();
        this.tv = tv;
    }

    @Override
    public void execute() {
        // 调用接收者的方法
        tv.off();
    }

    @Override
    public void undo() {
        // 调用接收者的方法
        tv.on();
    }
}
/**
 * @author: 德鑫
 * Description:
 * @Date: 2021/01/27
 */

public class TVOnCommand implements Command {

    // 聚合TVReceiver

    TVReceiver tv;

    // 构造器
    public TVOnCommand(TVReceiver tv) {
        super();
        this.tv = tv;
    }

    @Override
    public void execute() {
        // 调用接收者的方法
        tv.on();
    }

    @Override
    public void undo() {
        // 调用接收者的方法
        tv.off();
    }
}
/**
 * @author: 德鑫
 * Description:
 * @Date: 2021/01/27
 */

public class LightOffCommand implements Command {

    // 聚合LightReceiver

    LightReceiver light;

    // 构造器
    public LightOffCommand(LightReceiver light) {
        super();
        this.light = light;
    }

    @Override
    public void execute() {
        // 调用接收者的方法
        light.off();
    }

    @Override
    public void undo() {
        // 调用接收者的方法
        light.on();
    }
}
/**
 * @author: 德鑫
 * Description:
 * @Date: 2021/01/27
 */

public class LightOnCommand implements Command {
    LightReceiver light;

    public LightOnCommand(LightReceiver light) {
        super();
        this.light = light;
    }

    @Override
    public void execute() {
         light.on();
    }

    @Override
    public void undo() {
        light.off();
    }
}
/**
 * @author: 德鑫
 * Description:
 *  没有任何处理 空执行。用于初始化每一个按钮。当调用空命令时对象什么都不做
 * @Date: 2021/01/27
 */

public class NoCommand implements Command{
    @Override
    public void execute() {

    }

    @Override
    public void undo() {

    }
}

好的现在我们有一个控制层。我们假象现在手里是一个开关,那么我们则根据输入的参数来确定我们到的是对那一个家电是开还是关

/**
 * @author: 德鑫
 * Description:
 * @Date: 2021/01/27
 */

public class RemoteController {
    Command[] onCommands;
    Command[] offCommands;

    Command undoCommand;

    public RemoteController() {
        onCommands = new Command[5];
        offCommands = new Command[5];
        for (int i = 0; i < 5; i++) {
            onCommands[i] = new NoCommand();
            offCommands[i] = new NoCommand();
        }
    }

    // 给我们的按钮设置你需要的命令
    public void setCommand(int no, Command onCommand, Command offCommand) {
        onCommands[no] = onCommand;
        offCommands[no] = offCommand;
    }

    //按下开按钮
    public void onButtonWasPushed(int no){
        // 找到你按下的开的按钮, 并调用对应方法
        onCommands[no].execute();
        // 记录这次的操作,用于撤销
        undoCommand = onCommands[no];
    }

    // 按下开按钮
    public void offButtonWasPushed(int no) { // no 0
        // 找到你按下的关的按钮, 并调用对应方法
        offCommands[no].execute();
        // 记录这次的操作,用于撤销
        undoCommand = offCommands[no];
    }

    // 按下撤销按钮
    public void undoButtonWasPushed() {
        undoCommand.undo();
    }
}

最后写一个客户端来进行测试

这个客户端测试就是根据传入不同的类型。来调用不同的方法进行处理。这里也可以将接口替换成抽象类的形式

public class Client {
    public static void main(String[] args) {
        LightReceiver lightReceiver = new LightReceiver();
        //创建电灯相关的开关命令
        LightOnCommand lightOnCommand = new LightOnCommand(lightReceiver);

        LightOffCommand lightOffCommand = new LightOffCommand(lightReceiver);

        //遥控器
        RemoteController remoteController = new RemoteController();

        //给我们的遥控器设置命令, 比如 no = 0 是电灯的开和关的操作
        remoteController.setCommand(0, lightOnCommand, lightOffCommand);

        System.out.println("--------按下灯的开按钮-----------");
        remoteController.onButtonWasPushed(0);
        System.out.println("--------按下灯的关按钮-----------");
        remoteController.offButtonWasPushed(0);
        System.out.println("--------按下撤销按钮-----------");
        remoteController.undoButtonWasPushed();

        System.out.println("=========使用遥控器操作电视机==========");
        TVReceiver tvReceiver = new TVReceiver();

        TVOffCommand tvOffCommand = new TVOffCommand(tvReceiver);
        TVOnCommand tvOnCommand = new TVOnCommand(tvReceiver);

        //给我们的遥控器设置命令, 比如 no = 1 是电视机的开和关的操作
        remoteController.setCommand(1, tvOnCommand, tvOffCommand);

        System.out.println("--------按下电视机的开按钮-----------");
        remoteController.onButtonWasPushed(1);
        System.out.println("--------按下电视机的关按钮-----------");
        remoteController.offButtonWasPushed(1);
        System.out.println("--------按下撤销按钮-----------");
        remoteController.undoButtonWasPushed();
    }
}

三、命令模式的总结

  1. 命令模式(Command Pattern):在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收 者是谁,也不知道被请求的操作是哪个, 我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计 。
  2. 命名模式使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活,实现解耦。
  3. 在命名模式中,会将一个请求封装为一个对象,以便使用不同参数来表示不同的请求(即命名),同时命令模式 也支持可撤销的操作。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
设计模式GOF)是一本经典的设计模式教科书,由四位软件工程师(Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides)合著。该书首次于1994年出版,至今仍被广泛用于软件设计和开发中。 该书一共介绍了23种常用的设计模式,这些模式分为三个主要的分类:创建型模式、结构型模式和行为型模式。 创建型模式主要涉及对象的创建机制,包括单例模式、工厂模式、抽象工厂模式、建造者模式和原型模式。这些模式能够帮助开发人员根据需求来选择合适的创建对象的方式,从而提高系统的灵活性和可复用性。 结构型模式主要关注对象的组合方式和类之间的关系,包括适配器模式、桥接模式、装饰者模式、外观模式、享元模式和组合模式。这些模式能够帮助开发人员设计出高内聚、低耦合的系统结构,提高系统的扩展性和维护性。 行为型模式主要关注不同对象之间的交互方式,包括策略模式、观察者模式、迭代器模式命令模式、备忘录模式、状态模式、访问者模式、中介者模式和解释器模式。这些模式能够帮助开发人员实现对象之间的灵活通信,并且提供了可维护的系统行为。 设计模式GOF PDF是一本非常重要的参考书,它提供了详细的设计模式概念和实现代码示例。通过学习和理解这些模式,开发人员能够更好地应对复杂的软件设计和开发任务,提高代码质量和开发效率。 总之,设计模式GOF PDF是一本值得学习和阅读的书籍,对于软件开发人员来说具有重要的指导意义。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值