研磨设计模式day12命令模式

目录

定义

几个参数

场景描述

代码示例

参数化设置

命令模式的优点

本质 

何时选用


定义

几个参数

Command:定义命令的接口。

ConcreteCommand:命令接口的实现对象。但不是真正实现,是通过接收者的功能来完成命令要执行的操作

Receiver:接收者。真正执行命令的对象。任何类都可能成为一个接收者,只要它能够实现命令要求实现的相应功能

Invoker:要求命令对象执行请求,通常持有命令对象。

Client:创建具体的命令对象,并且设置命令对象的接收者。

场景描述

电脑开机:

机箱上的按钮就相当于是命令对象

机箱相当于是Invoker:要求机箱上的按钮执行哪些动作

主板相当于接收者对象:真正执行命令的对象

命令对象持有接收者对象就相当于按钮有一条线连接着主板,当按钮被按下就通过连接线把命令发出去。

代码示例

定义主板

package day12命令模式;

/**
 * 主板的接口
 */
public interface ZhuBanApi {
    /**
     * 定义一个功能:开机
     */
    public void open();
}

定义实现,定义两个一个是技嘉主板,一个是微星主板,现在将实现写为一样

不同的主板对同一个命令的操作可以是不同的

技嘉主板

package day12命令模式.Impl;

import day12命令模式.ZhuBanApi;

public class JiJiaZhuBanImpl implements ZhuBanApi {
    @Override
    public void open() {
        System.out.println("技嘉主板正在开机,请等候");
        System.out.println("接通电源......");
        System.out.println("设备检查......");
        System.out.println("装载系统......");
        System.out.println("机器正常运转......");
        System.out.println("机器已经正常打开,请操作");
    }
}

微星主板

package day12命令模式.Impl;

import day12命令模式.ZhuBanApi;

public class WeiXingZhuBanImpl implements ZhuBanApi {
    @Override
    public void open() {
        System.out.println("微星主板正在开机,请等候");
        System.out.println("接通电源......");
        System.out.println("设备检查......");
        System.out.println("装载系统......");
        System.out.println("机器正常运转......");
        System.out.println("机器已经正常打开,请操作");
    }
}

定义命令接口:里面只有一个方法就是执行

package day12命令模式;

/**
 * 命令接口,声明执行的操作
 */
public interface Command {
    /**
     * 执行命令对应的操作
     */
    public void execute();
}

命令实现:我们按下的是按钮,但是按钮本身不知道怎么去启动电脑,只有主板知道,所以我们要持有真正实现命令的接收者--主板对象

package day12命令模式.Impl;

import day12命令模式.Command;
import day12命令模式.ZhuBanApi;

/**
 * 开机命令接口的实现
 */
public class CommandImpl implements Command {
    /**
     * 持有真正实现命令的接收者--主板对象
     */
    private ZhuBanApi zhuBanApi = null;

    /**
     * 构造方法,传入主板对象
     * @param zhuBanApi
     */
    public CommandImpl(ZhuBanApi zhuBanApi){
        this.zhuBanApi = zhuBanApi;
    }

    /**
     * 实现开机
     */
    @Override
    public void execute() {
        this.zhuBanApi.open();
    }
}

提供机箱,按钮是放置在机箱上的。机箱对象,本身有按钮,持有按钮对应的命令对象也就是Command

package day12命令模式;

/**
 * 机箱对象,本身有按钮,持有按钮对应的命令对象
 */
public class Box {
    /**
     * 开机命令对象
     */
    private Command openCommand;

    /**
     * 设置开机命令对象
     * @param openCommand 开机命令对象
     */
    public void setOpenCommand(Command openCommand) {
        this.openCommand = openCommand;
    }
    /**
     * 提供给客户使用,接收并相应用户请求,相当于那妞被按下触发的方法
     */
    public void openButton(){
        openCommand.execute();
    }
}

客户使用按钮,把与主板连接好的按钮对象放置在机箱上。

package day12命令模式;

import day12命令模式.Impl.CommandImpl;
import day12命令模式.Impl.WeiXingZhuBanImpl;

public class Client {
    public static void main(String[] args) {
        // 1.创建接收者
        WeiXingZhuBanImpl zhuban = new WeiXingZhuBanImpl();

        // 2.设置接收者与命令对象的关系  (按钮要进行开机,使用哪个主板)
        CommandImpl command = new CommandImpl(zhuban);

        // 3.创建Invoker,用Invoker来执行命令
        Box box = new Box();
        // 4.将2中绑定好关系的命令对象设置到Invoker中,让Invoker持有
        box.setOpenCommand(command);

        // 5.调用Invoker中的方法,触发要求执行命令
        // Box定义了方法,,用持有命令对象接口里面的方法,接口的实现中持有真正实现命令的接收者ZhuBanApi,
        // ZhuBanApi他去调用真正的开机方法,而这个接口有多个实现类,到底调用哪一个呢?
        // 因为在创建接收者时已经把微星这个接收者与命令对象绑定起来了,所以用的就是微星的实现类
        box.openButton();
    }
}

解析:先new一个主板,主板要跟按钮连接成为一个具体的开机命令,我又new一个机箱,把这个升级过的按钮(带有功能)装到这个机箱上,机箱最后调用这个按钮。

1.会发现命令模式的关键之处就是把请求封装成了对象,也就是命令对象,并定义了统一的执行操作的接口。

2.在命令模式中会有一个组装者,他来维护虚实现与真实实现之间的关系

参数化设置

可以用不同的命令对象,去参数化配置客户的请求

定义主板接口,现在增加一个重启的按钮,因此主板加一个方法来实现重启功能

package day12命令模式;

/**
 * 主板的接口
 */
public interface ZhuBanApi {
    /**
     * 定义一个功能:开机
     */
    public void open();
    /**
     * 定义重启功能
     */
    public void reset();
}

 实现类也要改一下

技嘉的

package day12命令模式.Impl;

import day12命令模式.ZhuBanApi;

/**
 * 主板的实现
 */
public class JiJiaZhuBanImpl implements ZhuBanApi {
    @Override
    public void open() {
        System.out.println("技嘉主板正在开机,请等候");
        System.out.println("接通电源......");
        System.out.println("设备检查......");
        System.out.println("装载系统......");
        System.out.println("机器正常运转......");
        System.out.println("机器已经正常打开,请操作");
    }

    @Override
    public void reset() {
        System.out.println("技嘉主板现在正在重新启动机器,请等候");
        System.out.println("机器已经正常打开,请操作");
    }
}

微星的

package day12命令模式.Impl;

import day12命令模式.ZhuBanApi;

/**
 * 主板的实现
 */
public class WeiXingZhuBanImpl implements ZhuBanApi {
    @Override
    public void open() {
        System.out.println("微星主板正在开机,请等候");
        System.out.println("接通电源......");
        System.out.println("设备检查......");
        System.out.println("装载系统......");
        System.out.println("机器正常运转......");
        System.out.println("机器已经正常打开,请操作");
    }

    @Override
    public void reset() {
        System.out.println("微星主板现在正在重新启动机器,请等候");
        System.out.println("机器已经正常打开,请操作");
    }
}

接下来定义命令和按钮,接口不变,添加一个重启命令的实现resetCommandImpl

package day12命令模式.Impl;

import day12命令模式.Command;
import day12命令模式.ZhuBanApi;

public class ResetCommandImpl implements Command {
    /**
     * 持有主板,也就是接收者对象
     */
    private ZhuBanApi zhuBanApi;

    /**
     * 构造函数传入
     * @param zhuBanApi
     */
    public ResetCommandImpl(ZhuBanApi zhuBanApi){
        this.zhuBanApi = zhuBanApi;
    }
    @Override
    public void execute() {
        this.zhuBanApi.reset();
    }
}

Box改造一下,这里增加一个重启命令对象

package day12命令模式;

/**
 * 机箱对象,本身有按钮,持有按钮对应的命令对象
 */
public class Box {
    /**
     * 开机命令对象
     */
    private Command openCommand;

    /**
     * 重启命令对象
     */
    private Command resetCommand;

    public void setResetCommand(Command resetCommand) {
        this.resetCommand = resetCommand;
    }

    /**
     * 设置开机命令对象
     * @param openCommand 开机命令对象
     */
    public void setOpenCommand(Command openCommand) {
        this.openCommand = openCommand;
    }

    /**
     * 提供给客户使用,接收并相应用户请求,相当于按钮被按下触发的方法
     */
    public void openButton(){
        openCommand.execute();
    }

    /**
     * 重启按钮
     */
    public void resetButton(){
        resetCommand.execute();
    }
}

Client

package day12命令模式;

import day12命令模式.Impl.OpenCommandImpl;
import day12命令模式.Impl.ResetCommandImpl;
import day12命令模式.Impl.WeiXingZhuBanImpl;

public class Client {
    public static void main(String[] args) {

        WeiXingZhuBanImpl zhuban = new WeiXingZhuBanImpl();


        OpenCommandImpl openCommand = new OpenCommandImpl(zhuban);
        ResetCommandImpl resetCommand = new ResetCommandImpl(zhuban);


        Box box = new Box();
        box.setOpenCommand(openCommand);
        box.setResetCommand(resetCommand);

        System.out.println("正确配置");
        System.out.println(">>>按下开机按钮:>>>");
        box.openButton();
        System.out.println(">>>按下重启按钮:>>>");
        box.resetButton();
    }
}

命令模式的优点

本质 

命令模式的本质:封装请求

何时选用

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

kafka-python 消费者消费不到消息

排除步骤1: 使用group_id”consumer_group_id_001“ 和 auto_offset_reset"earliest" from kafka import KafkaConsumerconsumer KafkaConsumer(bootstrap_servers["dev-kafka01.test.xxx.cloud:9092"],enable_auto_commitTrue, auto_commit…

计算机安全学习笔记(I):访问控制安全原理

访问控制原理 从广义上来讲,所有的计算机安全都与访问控制有关。 RFC 4949: Internet Security Glossary, Version 2 (rfc-editor.org) RFC 4949 定义的计算机安全:用来实现和保证计算机系统的安全服务的措施,特别是保证访问控制服务的措施…

十几款拿来就能用的炫酷表白代码

「作者主页」:士别三日wyx 「作者简介」:CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」:小白零基础《Python入门到精通》 表白代码 1、坐我女朋友好吗,不同意就关机.vbs2、坐我女朋友好吗&…

使用 Transformer 和 Amazon OpenSearch Service 构建基于列的语义搜索引擎

在数据湖中,对于数据清理和注释、架构匹配、数据发现和跨多个数据来源进行分析等许多操作,查找相似的列有着重要的应用。如果不能从多个不同的来源准确查找和分析数据,就会严重拉低效率,不论是数据科学家、医学研究人员、学者&…

C# 实现 国密SM4/ECB/PKCS7Padding对称加密解密

C# 实现 国密SM4/ECB/PKCS7Padding对称加密解密,为了演示方便本问使用的是Visual Studio 2022 来构建代码的 1、新建项目,之后选择 项目 鼠标右键选择 管理NuGet程序包管理,输入 BouncyCastle 回车 添加BouncyCastle程序包 2、代码如下&am…

npm和yarn的区别?

文章目录 前言npm和yarn的作用和特点npm和yarn的安装的机制npm安装机制yarn安装机制检测包解析包获取包链接包构建包 总结后言 前言 这一期给大家讲解npm和yarn的一些区别 npm和yarn的作用和特点 包管理:npm 和 yarn 可以用于安装、更新和删除 JavaScript 包。它们提…

识别图片中的文字

前言 PearOCR 是一款免费无限制网页版文字识别工具。 优点如下: 免费:完全免费,没有任何次数、大小限制,可以无限使用; 安全:全部数据本地运算,所有图片均不会被上传; 智能&#xf…

市场的新宠:4G智能手表

现在人们提到智能手表,健康监测、运动记录、接打电话等定是他不可或缺的功能,而其中通讯功能在绝大数多的智能手表上都是通过蓝牙实现的,需要让手表通过蓝牙连接到手机端来进行。在没有手机的情况下,配置再高的蓝牙智能手表也是“…

Kubernetes入门 十、HPA 自动扩/缩容

目录 概述安装metrics-server使用HPA 概述 我们已经可以通过手动执行 kubectl scale 命令实现Pod的扩缩容,但是这显然不符合 Kubernetes 的定位目标–自动化和智能化。Kubernetes 期望可以通过监测Pod的使用情况,实现 Pod 数量的自动调整,于…

成都瀚网科技:抖店如何经营?

作为热门的短视频分享平台,抖音不仅是一种娱乐工具,更是一个蕴藏着无限商机的电商平台。开店、抖音下单成为很多人的选择。那么,抖音如何开店、下单呢? 1、如何在抖音上开店和下单? 注册账号:首先&#xff…

5.网络原理之初识

文章目录 1.网络发展史1.1独立模式1.2网络互连1.3局域网LAN1.3.1基于网线直连1.3.2基于集线器组建1.3.3基于交换机组建1.3.4基于交换机和路由器组建1.3.4.1路由器和交换机区别 1.4广域网WAN 2.网络通信基础2.1IP地址2.2端口号2.3认识协议2.4五元组2.5 协议分层2.5.1 分层的作用…

SpringMVC-2-Spring MVC拦截器详解:从入门到精通

SpringMVC-2-Spring MVC拦截器详解:从入门到精通 今日目标 能够编写拦截器并配置拦截器 1.拦截器【理解】 1 拦截器介绍 1.1 拦截器概念和作用 拦截器(Interceptor)是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方…

上海亚商投顾:创业板指反弹大涨1.26% 核污染概念股午后全线走强

上海亚商投顾前言:无惧大盘涨跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。 市场情绪 三大指数今日集体反弹,沪指午后冲高回落,创业板指盘中涨超2%,尾盘涨幅也有所收…

Electron学习3 使用serialport操作串口

Electron学习3 使用serialport操作串口 一、准备工作二、 SerialPort 介绍1. 核心软件包(1) serialport(2) serialport/stream(3) serialport/bindings-cpp(4) serialport/binding-mock(5) serialport/bindings-interface 2. 解析器包3. 命令行工具 三、创建一个demo程序1. 创建…

元类(metaclass)

目录 一、引言 二、什么是元类 三、为什么用元类 四、内置函数exec(储备) 五、class创建类 5.1 type实现 六、自定义元类控制类的创建 6.1 应用 七、__call__(储备) 八、__new__(储备) 九、自定义元类控制类的实例化 一十、自定义元类后类的继承顺序 十一、练习 p…

Go1.19 排序算法设计实践 经典排序算法对比

详解经典排序算法 01 为什么要学习数据结构与算法 抖音直播排行榜功能 案例 规则:某个时间段内,直播间礼物数TOP10房间获得奖励,需要在每个房间展示排行榜解决方案 •礼物数量存储在Redis-zset中,使用skiplist使得元素整体有序 •…

ImportError: cannot import name ‘SQLDatabaseChain‘ from ‘langchain‘解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

第三方检测检验实验室信息化建设

检测公司配置先进的信息化管理系统,信息化管理系统采用适宜的、先进的架构,具备开放性、扩展性、前瞻性、安全性等。先期建设按照实验室的规格及整体配套设施,整个实验室信息化系统的结构化数据考虑本地存储,且应考虑高速存储应用…

树莓派自带的GPIO串口输出及输出乱码问题解决方案

可以使用树莓派的UART0进行串口输出,具体连接方法如图所示: 连接后可以使用如下代码发送串口数据: import serial import time# 串口初始化 ser serial.Serial(/dev/serial0, 9600, timeout1) # /dev/serial0 是树莓派上默认的串口设备# 发…

构建 NodeJS 影院预订微服务并使用 docker 部署(04/4)

一、说明 构建一个微服务的电影网站,需要Docker、NodeJS、MongoDB,这样的案例您见过吗?如果对此有兴趣,您就继续往下看吧。 我们前几章的快速回顾 第一篇文章介绍了微服务架构模式,并讨论了使用微服务的优缺点。第二篇…