《HeadFirst设计模式(第二版)》第六章代码——命令模式

news2024/12/23 9:26:07
代码文件目录:

Command
package Chapter6_CommandPattern.Command;

/**
 * @Author 竹心
 * @Date 2023/8/6
 **/

public interface Command {
    public void execute();
    public void undo();//撤销该指令
}
CeilingFan
package Chapter6_CommandPattern.ElectricAppliance;

/**
 * @Author 竹心
 * @Date 2023/8/6
 **/

//吊扇
public class CeilingFan {

    public static final int HIGH = 3;
    public static final int MEDIUM = 2;
    public static final int LOW = 1;
    public static final int OFF = 0;
    String location;
    int speed;

    public CeilingFan(String location){
        this.location = location;
        this.speed = OFF;
    }

    public void high(){
        this.speed = HIGH;
        System.out.println(this.location+" ceilingFan is on High");
    }

    public void medium(){
        this.speed = MEDIUM;
        System.out.println(this.location+" ceilingFan is on Medium");
    }

    public void low(){
        this.speed = LOW;
        System.out.println(this.location+" ceilingFan is on Low");
    }

    public void off(){
        this.speed = OFF;
        System.out.println(this.location+" ceilingFan is on Off");
    }

    public int getSpeed(){
        return this.speed;
    }

}
CeilingFanHighCommand
package Chapter6_CommandPattern.Command;

import Chapter6_CommandPattern.ElectricAppliance.CeilingFan;

/**
 * @Author 竹心
 * @Date 2023/8/6
 **/

public class CeilingFanHighCommand implements Command{
    CeilingFan ceilingFan;
    int prevSpeed;//保存上一个挡位

    public CeilingFanHighCommand(CeilingFan ceilingFan){
        this.ceilingFan = ceilingFan;
    }

    @Override
    public void execute() {
        this.prevSpeed = this.ceilingFan.getSpeed();
        this.ceilingFan.high();
    }

    @Override
    public void undo() {
        if(this.prevSpeed==CeilingFan.HIGH){
            this.ceilingFan.high();
        }else if(this.prevSpeed == CeilingFan.MEDIUM){
            this.ceilingFan.medium();
        }else if(this.prevSpeed == CeilingFan.LOW){
            this.ceilingFan.low();
        }else if(this.prevSpeed == CeilingFan.OFF){
            this.ceilingFan.off();
        }
    }
}
Light
package Chapter6_CommandPattern.ElectricAppliance;

/**
 * @Author 竹心
 * @Date 2023/8/6
 **/

public class Light {
    String name;

    public Light(String name){
        this.name = name;
    }

    public void on(){
        System.out.println(this.name+" light is on!");
    }
    public void off(){
        System.out.println(this.name+" light is off!");
    }
}
LightOnCommand
package Chapter6_CommandPattern.Command;

import Chapter6_CommandPattern.Command.Command;
import Chapter6_CommandPattern.ElectricAppliance.Light;

/**
 * @Author 竹心
 * @Date 2023/8/6
 **/

public class LightOnCommand implements Command {
    Light light;

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

    @Override
    public void execute() {
        //当遥控器运行这个指令的时候,并不知道灯是如何实现打开开关的
        //实现遥控器与电器之间的解耦合
        this.light.on();
    }

    @Override
    public void undo() {
        this.light.off();
    }
}
LightOffCommand
package Chapter6_CommandPattern.Command;

import Chapter6_CommandPattern.ElectricAppliance.Light;

/**
 * @Author 竹心
 * @Date 2023/8/6
 **/

public class LightOffCommand implements Command{
    Light light;

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

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

    public void undo() {
        this.light.on();
    }
}
GarageDoor
package Chapter6_CommandPattern.ElectricAppliance;

/**
 * @Author 竹心
 * @Date 2023/8/6
 **/

public class GarageDoor {
    Light light;

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

    public void up(){
        this.lightOn();
        System.out.println("the garage door is open!");
    }

    public void down(){
        this.lightOff();
        System.out.println("the garage door is closed");
    }

    private void lightOn(){
        this.light.on();
    }

    private void lightOff(){
        this.light.off();
    }
}
GarageDoorOpenCommand
package Chapter6_CommandPattern.Command;

import Chapter6_CommandPattern.ElectricAppliance.GarageDoor;

/**
 * @Author 竹心
 * @Date 2023/8/6
 **/

public class GarageDoorOpenCommand implements Command{
    GarageDoor garageDoor;

    public GarageDoorOpenCommand(GarageDoor garageDoor){
        this.garageDoor = garageDoor;
    }

    @Override
    public void execute() {
        this.garageDoor.up();
    }

    public void undo() {
        this.garageDoor.down();
    }
}
GarageDoorCloseCommand
package Chapter6_CommandPattern.Command;

import Chapter6_CommandPattern.ElectricAppliance.GarageDoor;

/**
 * @Author 竹心
 * @Date 2023/8/6
 **/

public class GarageDoorCloseCommand implements Command{
    GarageDoor garageDoor;

    public GarageDoorCloseCommand(GarageDoor garageDoor){
        this.garageDoor = garageDoor;
    }

    @Override
    public void execute() {
        this.garageDoor.down();
    }

    public void undo() {
        this.garageDoor.down();
    }
}
Stereo
package Chapter6_CommandPattern.ElectricAppliance;

/**
 * @Author 竹心
 * @Date 2023/8/6
 **/

public class Stereo {
    int volume;
    //音响类
    public void on(){
        System.out.println("the stereo is on!");
    }
    public void off(){
        System.out.println("the stereo is off!");
    }

    public void setCD(){
        System.out.println("the stereo can work with CD now!");
    }

    public void setDVD(){
        System.out.println("the stereo can work with DVD now!");
    }

    public void setVolume(int volume){//设置音量
        this.volume = volume;
    }
}
StereoOnWithCDCommand
package Chapter6_CommandPattern.Command;

import Chapter6_CommandPattern.ElectricAppliance.Stereo;

/**
 * @Author 竹心
 * @Date 2023/8/6
 **/

public class StereoOnWithCDCommand implements Command{
    Stereo stereo;

    public StereoOnWithCDCommand(Stereo stereo){
        this.stereo = stereo;
    }

    @Override
    public void execute() {
        this.stereo.on();
        this.stereo.setCD();
        this.stereo.setVolume(6);
    }

    @Override
    public void undo() {
        this.stereo.off();
    }
}
StereoOff
package Chapter6_CommandPattern.Command;

import Chapter6_CommandPattern.ElectricAppliance.Stereo;

/**
 * @Author 竹心
 * @Date 2023/8/6
 **/

public class StereoOff implements  Command{
    Stereo stereo;

    public StereoOff(Stereo stereo){
        this.stereo = stereo;
    }

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

    public void undo() {
        this.stereo.on();
        this.stereo.setCD();
        this.stereo.setVolume(6);
    }
}
MacroCommand
package Chapter6_CommandPattern.Command;

/**
 * @Author 竹心
 * @Date 2023/8/6
 **/

//宏指令
public class MacroCommand implements Command{
    Command[] commands;
    public MacroCommand(Command[] commands){
        this.commands = commands;
    }

    @Override
    public void execute() {
        for(int i=0;i<this.commands.length;++i){
            this.commands[i].execute();
        }
    }

    @Override
    public void undo() {
        for(int i=0;i<this.commands.length;++i){
            this.commands[i].undo();
        }
    }
}
NoCommand
package Chapter6_CommandPattern.Command;

/**
 * @Author 竹心
 * @Date 2023/8/6
 **/

public class NoCommand implements Command{
    @Override
    public void execute() {
        //this command is useless!
    }

    @Override
    public void undo() {

    }
}
RemoteControl
package Chapter6_CommandPattern;

import Chapter6_CommandPattern.Command.Command;
import Chapter6_CommandPattern.Command.NoCommand;

import java.util.Arrays;

/**
 * @Author 竹心
 * @Date 2023/8/6
 **/

//遥控器类
public class RemoteControl {
    Command[] onCommands;
    Command[] offCommands;
    Command undoCommand;

    public RemoteControl(){
        //为简洁起见,这里遥控器只有3个槽位
        this.onCommands = new Command[7];
        this.offCommands = new Command[7];

        Command noCommand = new NoCommand();
        //这里使用空对象,是为了后面不用写 if(onCommand[i]==null){...}
        for(int i =0;i<7;++i){
            this.onCommands[i] = noCommand;
            this.offCommands[i] = noCommand;
        }
        this.undoCommand = noCommand;
    }

    //设置某个电器的开关命令
    public void setCommand(int slot, Command onCommand, Command offCommand){
        this.onCommands[slot] = onCommand;
        this.offCommands[slot] = offCommand;
    }

    public void onButtonWasPushed(int slot){
        this.onCommands[slot].execute();
        this.undoCommand = this.onCommands[slot];
    }

    public void offButtonWasPushed(int slot){
        this.offCommands[slot].execute();
        this.undoCommand = this.offCommands[slot];
    }

    public void undoButtonWasPushed(){
        this.undoCommand.undo();
    }

    @Override
    public String toString() {
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("\n---------- Remote Control ----------\n");
        for(int i = 0;i<this.onCommands.length;i++){
            stringBuffer.append("[slot "+ i +"] "+
                    String.format("%-30s",this.onCommands[i].getClass().getSimpleName())+
                    String.format("%-30s",this.offCommands[i].getClass().getSimpleName())+"\n"
            );
        }
        stringBuffer.append("[undo] "+this.undoCommand.getClass().getSimpleName());
        return stringBuffer.toString();
    }
}
RemoteLoader
package Chapter6_CommandPattern;

import Chapter6_CommandPattern.Command.*;
import Chapter6_CommandPattern.ElectricAppliance.CeilingFan;
import Chapter6_CommandPattern.ElectricAppliance.GarageDoor;
import Chapter6_CommandPattern.ElectricAppliance.Light;
import Chapter6_CommandPattern.ElectricAppliance.Stereo;

/**
 * @Author 竹心
 * @Date 2023/8/6
 **/

public class RemoteLoader {
    public static void main(String[] args) {
        RemoteControl remoteControl = new RemoteControl();

        //创建设备
        Light LivingRoomLight = new Light("LivingRoom");
        Light KitchenLight = new Light("Kitchen");
        Light GarageLight = new Light("Garage");
        GarageDoor garageDoor = new GarageDoor(GarageLight);
        Stereo stereo = new Stereo();

        //创建命令对象
        LightOnCommand livingRoomLightOn =new LightOnCommand(LivingRoomLight);
        LightOnCommand kitchenLightOn = new LightOnCommand(KitchenLight);
        GarageDoorOpenCommand garageDoorOpenCommand =
                new GarageDoorOpenCommand(garageDoor);
        StereoOnWithCDCommand stereoOnWithCDCommand =
                new StereoOnWithCDCommand(stereo);

        LightOffCommand lightOffCommand = new LightOffCommand(LivingRoomLight);
        LightOffCommand kitchenLightOff = new LightOffCommand(KitchenLight);
        GarageDoorCloseCommand garageDoorCloseCommand =
                new GarageDoorCloseCommand(garageDoor);
        StereoOff stereoOff = new StereoOff(stereo);

        //将命令加载进入槽位
        remoteControl.setCommand(0,livingRoomLightOn,lightOffCommand);
        remoteControl.setCommand(1,kitchenLightOn,kitchenLightOff);
        remoteControl.setCommand(2,garageDoorOpenCommand,garageDoorCloseCommand);
        remoteControl.setCommand(3,stereoOnWithCDCommand,stereoOff);

        //展示
//        System.out.println(remoteControl);

        remoteControl.onButtonWasPushed(0);
        remoteControl.onButtonWasPushed(1);
        remoteControl.onButtonWasPushed(2);
        remoteControl.onButtonWasPushed(3);

        remoteControl.offButtonWasPushed(0);
        remoteControl.offButtonWasPushed(1);
        remoteControl.offButtonWasPushed(2);
        remoteControl.offButtonWasPushed(3);

        //使用lambda简洁编写代码
        //增加撤销按钮后就不能使用了
        //这样就不用写一大堆命令类了
//        remoteControl.setCommand(4,()->LivingRoomLight.on(),
//                ()->LivingRoomLight.off());

        //测试撤销功能
        System.out.println("\n测试撤销:");
        remoteControl.onButtonWasPushed(0);
        remoteControl.undoButtonWasPushed();

        //测试风扇
        System.out.println("test fan");
        CeilingFan ceilingFan = new CeilingFan("livingRoom");
        CeilingFanHighCommand command = new CeilingFanHighCommand(ceilingFan);
        remoteControl.setCommand(4,command,command);

        System.out.println(remoteControl);

        remoteControl.onButtonWasPushed(4);
        System.out.println(remoteControl);

        remoteControl.undoButtonWasPushed();

        //测试宏指令
        System.out.println("\n宏指令");
        Light light1 = new Light("Room1");
        Light light2 = new Light("Room2");
        Light light3 = new Light("Room3");
        Light light4 = new Light("Room4");

        LightOnCommand lightOnCommand1 = new LightOnCommand(light1);
        LightOnCommand lightOnCommand2 = new LightOnCommand(light2);
        LightOnCommand lightOnCommand3 = new LightOnCommand(light3);
        LightOnCommand lightOnCommand4 = new LightOnCommand(light4);

        LightOffCommand lightOffCommand1 = new LightOffCommand(light1);
        LightOffCommand lightOffCommand2 = new LightOffCommand(light2);
        LightOffCommand lightOffCommand3 = new LightOffCommand(light3);
        LightOffCommand lightOffCommand4 = new LightOffCommand(light4);

        Command[] onCommands = {lightOnCommand1,lightOnCommand2,lightOnCommand3,lightOnCommand4};
        Command[] offCommand = {lightOffCommand1,lightOffCommand2,lightOffCommand3,lightOffCommand4};
        MacroCommand partyOn = new MacroCommand(onCommands);
        MacroCommand partyOff = new MacroCommand(offCommand);

        remoteControl.setCommand(5,partyOn,partyOff);

        System.out.println(remoteControl);
        remoteControl.onButtonWasPushed(5);
        remoteControl.offButtonWasPushed(5);
        remoteControl.undoButtonWasPushed();


    }
}
SimpleRemoteControl
package Chapter6_CommandPattern;

import Chapter6_CommandPattern.Command.Command;

/**
 * @Author 竹心
 * @Date 2023/8/6
 **/

public class SimpleRemoteControl {
    Command slot;//目前该遥控器只支持一个槽位

    public SimpleRemoteControl(){}

    public void setCommand(Command command){
        this.slot = command;
    }

    public void buttonWasPressed(){
        this.slot.execute();
    }

}
RemoteControlTest
package Chapter6_CommandPattern;

import Chapter6_CommandPattern.Command.GarageDoorOpenCommand;
import Chapter6_CommandPattern.ElectricAppliance.GarageDoor;
import Chapter6_CommandPattern.ElectricAppliance.Light;

/**
 * @Author 竹心
 * @Date 2023/8/6
 **/

public class RemoteControlTest {
    public static void main(String[] args) {
        SimpleRemoteControl remote = new SimpleRemoteControl();
        Light light = new Light("garage light");
        GarageDoor garageDoor = new GarageDoor(light);
        GarageDoorOpenCommand garageDoorOpen = new GarageDoorOpenCommand(garageDoor);

        remote.setCommand(garageDoorOpen);
        remote.buttonWasPressed();
    }
}
notes.txt
命令模式:
    把请求封装成为对象,以便对不同的请求、队列或者日志请求来参数化对象,
    并支持可撤销的操作

命令对象只暴露一个方法:execute(),命令的请求者不会知道执行者具体如何实现指令

当需要将发出请求的对象和能够实行请求的对象解耦合的时候可以使用命令模式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/841274.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

阿里云快速部署开发环境 (Apache + Mysql8.0+Redis7.0.x)

本文章的内容截取于云服务器管理控制台提供的安装步骤&#xff0c;再整合前人思路而成&#xff0c;文章末端会提供原文连接 ApacheMysql 8.0部署MySQL数据库&#xff08;Linux&#xff09;步骤一&#xff1a;安装MySQL步骤二&#xff1a;配置MySQL步骤三&#xff1a;远程访问My…

协议,序列化,反序列化,Json

文章目录 协议序列化和反序列化网络计算器protocol.hppServer.hppServer.ccClient.hppClient.cclog.txt通过结果再次理解通信过程 Json效果 协议 协议究竟是什么呢&#xff1f;首先得知道主机之间的网络通信交互的是什么数据&#xff0c;像平时使用聊天APP聊天可以清楚&#x…

【网络编程】利用套接字实现一个简单的网络通信(UDP实现聊天室 附上源码)

网络编程套接字 &#x1f41b;预备知识&#x1f98b;理解源IP地址和目的IP地址&#x1f40c;认识端口号&#x1f41e; 理解 "端口号" 和 "进程ID"&#x1f41c;简单认识TCP协议&#x1f99f;简单认识UDP协议&#x1f997; 什么是网络字节序 &#x1f577;相…

MySQL的关键指标及采集方法

MySQL 是个服务&#xff0c;所以我们可以借用 Google 四个黄金指标的思路来解决问题。 1、延迟 应用程序会向 MySQL 发起 SELECT、UPDATE 等操作&#xff0c;处理这些请求花费了多久&#xff0c;是非常关键的&#xff0c;甚至我们还想知道具体是哪个 SQL 最慢&#xff0c;这样…

【Linux】进程间通信——System V信号量

目录 写在前面的话 一些概念的理解 信号量的引入 信号量的概念及使用 写在前面的话 System V信号量是一种较低级的IPC机制&#xff0c;使用的时候需要手动进行操作和同步。在现代操作系统中&#xff0c;更常用的是POSIX信号量&#xff08;通过sem_*系列的函数进行操作&…

linux系统虚拟主机开启支持Swoole Loader扩展

特别说明&#xff1a;只是安装支持Swoole扩展&#xff0c;主机并没有安装服务端。目前支持版本php5.4-php7.2。 1、登陆主机控制面板&#xff0c;找到【远程文件下载】这个功能。 2、远程下载文件填写http://download.myhostadmin.net/vps/SwooleLoader_linux.zip 下载保存的路…

SpringBoot 升级内嵌Tomcat

SpringBoot 更新 Tomcat 最近公司的一个老项目需要升级下Tomcat&#xff0c;由于这个项目我完全没有参与&#xff0c;所以一开始我以为是一个老的Tomcat项目&#xff0c;升级它的Tomcat依赖或者是Tomcat容器镜像&#xff0c;后面发现是一个SpringBoot项目&#xff0c;升级的是…

加速中产 “返贫” 的4个迹象

没有消息&#xff0c;就是好消息。这话放在现在的朋友圈子里&#xff0c;似乎很合适。最近接到两个朋友的电话&#xff0c;一个是朋友的诉苦电话&#xff0c;这位朋友曾是某大厂的高管&#xff0c;被裁后失业近1年&#xff0c;虽然当初赔了N1&#xff0c;但架不住这位朋友“房贷…

Maven 打包生成Windows和Liunx启动文件

新建一个springboot项目。 1、项目结构 2、pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocati…

ASP.NET Core MVC -- 将视图添加到 ASP.NET Core MVC 应用

Index页 右键单击“视图”文件夹&#xff0c;然后单击“添加”>>“新文件夹”&#xff0c;并将文件夹命名为“HelloWorld”。 右键单击“Views/HelloWorld”文件夹&#xff0c;然后单击“添加”>“新项”。 在“添加新项 - MvcMovie”对话框中&#xff1a; 在右上…

Misc取证学习

文章目录 Misc取证学习磁盘取证工具veracryto挂载fat文件DiskGenius 磁盘取证例题[RCTF2019]disk 磁盘[](https://ciphersaw.me/ctf-wiki/misc/disk-memory/introduction/#_2)内存取证工具volatility 内存取证例题数字取证赛题0x01.从内存中获取到用户admin的密码并且破解密码 …

gin和gorm框架安装

理论上只要这两句命令 go get -u gorm.io/gorm go get -u github.com/gin-gonic/gin然而却出现了问题 貌似是代理问题&#xff0c;加上一条命令 go env -w GOPROXYhttps://goproxy.cn,direct 可以成功安装 安装gorm的数据库驱动程序 go get -u gorm.io/driver/mysql

香港人力资源服务商迦里仕人才,申请纳斯达克IPO上市

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 猛兽财经获悉&#xff0c;总部位于香港的人力资源服务商迦里仕人才&#xff08;Galaxy Payroll Group&#xff09;近期已向美国证券交易委员会&#xff08;SEC&#xff09;提交招股书&#xff0c;申请在纳斯达克IPO上市&am…

VUE框架:vue2转vue3全面细节总结(4)滚动行为

大家好&#xff0c;我是csdn的博主&#xff1a;lqj_本人 这是我的个人博客主页&#xff1a; lqj_本人_python人工智能视觉&#xff08;opencv&#xff09;从入门到实战,前端,微信小程序-CSDN博客 最新的uniapp毕业设计专栏也放在下方了&#xff1a; https://blog.csdn.net/lbcy…

Redis可视化工具

Redis可视化工具 1、RedisInsight 下载地址&#xff1a;https://redis.com/redis-enterprise/redis-insight/ 双击软件进行安装&#xff0c;安装完后弹出如下界面&#xff1a; 安装完成后在主界面选择添加Redis数据库&#xff1b; 选择手动添加数据库&#xff0c;输入Redis…

GD32F103VE独立看门狗

GD32F103VE独立看门狗 看门狗定时器(WDGT)有两个&#xff1a; 1&#xff0c;独立看门狗定时器(FWDGT) 2&#xff0c;窗口看门狗定时器(WWDGT) 独立看门狗定时器(FWDGT)有一个独立的时钟源(IRC40K). 独立看门狗定时器有一个向下计数器,当计数器到达0&#xff0c;会让CPU复位。…

二叉树的前序遍历、中序遍历、后序遍历、层次遍历的实现

DLR–前序遍历&#xff08;根在前&#xff0c;从左往右&#xff0c;一棵树的根永远在左子树前面&#xff0c;左子树又永远在右子树前面 &#xff09; LDR–中序遍历&#xff08;根在中&#xff0c;从左往右&#xff0c;一棵树的左子树永远在根前面&#xff0c;根永远在右子树前…

从0到1开发go-tcp框架【4实战片— — 开发MMO之玩家聊天篇】

从0到1开发go-tcp框架【实战片— — 开发MMO】 MMO&#xff08;MassiveMultiplayerOnlineGame&#xff09;&#xff1a;大型多人在线游戏&#xff08;多人在线网游&#xff09; 1 AOI兴趣点的算法 游戏中的坐标模型&#xff1a; 场景相关数值计算 ● 场景大小&#xff1a; 250…

Vue2:组件基础(下)

Vue2&#xff1a;组件基础&#xff08;下&#xff09; Date: April 12, 2023 Sum: props验证、计算属性、自定义时间、组件上的v-model、任务列表案例 Tags: * 目标&#xff1a; 能够知道如何对 props 进行验证 能够知道如何使用计算属性 令能够知道如何为组件自定义事件 …

K8S系列文章 之 容器网络基础 Docker0

什么是Docker0 使用ip addr命令看一下网卡&#xff1a; rootKitDevVps:~# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host…