23种设计模式学习记录之命令模式

想说的话:
在大学的时候曾经学过这23种设计模式,但是那时没啥编程经验,糊里糊涂过了一遍,没多久就忘记了,工作之后将精力主要集中在学习新技术上,比如springboot,cloud,docker,vue。毕业两年后去面试,发现设计模式还是java程序员需要迈过的一道坎,面试的时候问到代理模式和适配器模式有什么区别,你在工作中用到了什么设计模式,怎么用的?答不上来的特别尴尬,所以决定重新学习这几种设计模式,争取在工作中使用上。

本文所有案例代码

码云:https://gitee.com/helloworld6379/designPattern
Github:Github地址

设计模式概述

1 设计模式是程序员在面对同类软件工程设计问题所总结出来的有用的经验,模式不是代码,而是某类问题的通
用解决方案,设计模式(Design pattern)代表了最佳的实践。这些解决方案是众多软件开发人员经过相当长的
一段时间的试验和错误总结出来的。
2 设计模式的本质提高 软件的维护性,通用性和扩展性,并降低软件的复杂度。
3 设计模式并不局限于某种语言,java,php,c++ 都有设计模式.

设计模式类型
设计模式分为三种类型,共 23 种
1 创建型模式:单例模式、抽象工厂模式、原型模式、建造者模式、工厂模式。
2 结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
3 行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter 模式)、状态模式、策略模式、职责链模式(责任链模式)。

简单介绍

  1. 命令模式(Command Pattern):在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收 者是谁,也不知道被请求的操作是哪个, 我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计
  2. 命名模式使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活,实现解耦。
  3. 在命名模式中,会将一个请求封装为一个对象,以便使用不同参数来表示不同的请求(即命名),同时命令模式也支持可撤销的操作。

实现

实现智能家居,遥控器既能开关电灯泡又能开关电视。

UML图
23种设计模式学习记录之命令模式_第1张图片

/**
* @Description 
* @Author: LiuXing
* @Date: 2020/5/28 21:32
*/
public interface Command {
     
    //执行动作(操作)
    public void execute();
    // 撤销动作(操作)
    public void undo();
}
/**
* @Description 
* @Author: LiuXing
* @Date: 2020/5/28 21:32
*/
public class Light {
     
    public void on(){
      System.out.println(" 电灯打开了.."); }
    public void off(){
      System.out.println(" 电灯关闭了.."); }
}

/**
* @Description 
* @Author: LiuXing
* @Date: 2020/5/28 21:32
*/
public class LightOnCommand implements Command {
     

    private Light light;

    public LightOnCommand(Light light){
     
        this.light = light;
    }

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

    @Override
    public void undo() {
     
        light.off();
    }
}
/**
* @Description 
* @Author: LiuXing
* @Date: 2020/5/28 21:32
*/
public class LightOffCommand implements Command {
     

    private Light light;

    public LightOffCommand(Light light){
     
        this.light = light;
    }

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

    @Override
    public void undo() {
     
        light.on();
    }
}
/**
 * @Description
 * @Author: LiuXing
 * @Date: 2020/5/28 21:32
 */
public class TV {
     
    public void on(){
      System.out.println(" 电视机打开了.."); }
    public void off(){
      System.out.println(" 电视机关闭了.."); }
}

/**
 * @Description
 * @Author: LiuXing
 * @Date: 2020/5/28 21:32
 */
public class TVOffCommand implements Command {
     

    private TV tv;

    public TVOffCommand(TV tv){
     
        this.tv = tv;
    }

    @Override
    public void execute() {
     
        tv.off();
    }

    @Override
    public void undo() {
     
        tv.on();
    }
}
/**
 * @Description
 * @Author: LiuXing
 * @Date: 2020/5/28 21:32
 */
public class TVOnCommand implements Command {
     

    // 聚合TV
    private TV tv;

    public TVOnCommand(TV tv){
     
        this.tv = tv;
    }

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

    @Override
    public void undo() {
     
        tv.off();
    }
}
/**
* @Description  没有任何命令,即空执行: 用于初始化每个按钮, 当调用空命令时,对象什么都不做。其实,这样是一种设计模式, 可以省掉对空判断
* @Author: LiuXing
* @Date: 2020/5/28 21:33
*/
public class NoCommand implements Command {
     
    @Override
    public void execute() {
     

    }

    @Override
    public void undo() {
     

    }
}
/**
* @Description 
* @Author: LiuXing
* @Date: 2020/5/28 21:33
*/
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) {
     // no0
        // 找到你按下的开的按钮, 并调用对应方法
        onCommands[no].execute();
        // 记录这次的操作,用于撤销
        undoCommand = onCommands[no];
    }

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

    // 按下撤销按钮
    public void undoButtonWasPushed() {
     
        undoCommand.undo();
    }
    
}
/**
* @Description 
* @Author: LiuXing
* @Date: 2020/5/28 21:32
*/
public class CommandTest {
     

    public static void main(String[] args) {
     
        //使用命令设计模式,完成通过遥控器,对电灯的操作
        //创建电灯的对象(接受者)
        Light light = new Light();
        //创建电灯相关的开关命令
        LightOnCommand lightOnCommand = new LightOnCommand(light);

        LightOffCommand lightOffCommand = new LightOffCommand(light);
        //需要一个遥控器
        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("=========使用遥控器操作电视机==========");
        TV tv = new TV();
        TVOffCommand tvOffCommand = new TVOffCommand(tv);
        TVOnCommand tvOnCommand = new TVOnCommand(tv);
        //给我们的遥控器设置命令, 比如 no=1 是电视机的开和关的操作
        remoteController.setCommand(1, tvOnCommand, tvOffCommand);
        System.out.println("--------按下电视机的开按钮-----------");
        remoteController.onButtonWasPushed(1);
        System.out.println("--------按下电视机的关按钮-----------");
        remoteController.offButtonWasPushed(1);
        System.out.println("--------按下撤销按钮-----------");
        remoteController.undoButtonWasPushed();
    }
}

PS: 感觉这种模式貌似并没有在哪用到过,才识疏浅,大家在工作中有实际应用可以交流下。
文章介绍和代码都是CV过来的,UML图是自己画的。

你可能感兴趣的:(设计模式)