Java设计模式 - 命令模式

生命不息,写作不止

继续踏上学习之路,学之分享笔记

总有一天我也能像各位大佬一样

一个有梦有戏的人 @怒放吧德德

分享学习心得,欢迎指正,大家一起学习成长!

简介

命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。

                                                                                                                                                    ———— 菜鸟联盟

命令模式解析

命令模式会将一个请求封装为一个接口对象,由各种功能去实现其方法,在详细命令类中,通过聚合的方式将具体方法进行抽取调用。

UML图:

命令模式角色和职责

1)、Invoker:调用者角色

2)、Command:命令角色,需要执行的所有命令,(抽象类或接口)

3)、Receiver:命令接受者,知道如何实施执行某个命令

4)、ConcreteCommand:将一个接受对象和一个命令相互绑定,调用具体应操作的方法。

命令模式实例

通过智能家居的例子来学习命令模式,有一个遥控器,上面集成了好多台设备的开关操作,有灯光、电视等控制按钮。采用命令模式来管理控制,具体以下一步一步解析。首先看看具体的类图:

本次的类结构看起来比较复杂,其实原理都是Java面向对象。

本次实验通过定义命令接口,里面包含执行的命令,在通过各种各样设备去实现命令接口及其方法,不同设备的不同操作,如开、关,各种视为一个类,在这个类中实现不同的操作方法,虽然命令不同,但是可以通过聚合的方式,使用命令接受者类中去实现具体的不同方法进行分别调用。最后定义遥控器定义命令组并且为按钮去绑定相应的实现命令。

代码如下,会一步一步解释。

①、定义命令角色

命令角色可以是接口也可以是抽象类,根据本次的案例设计为接口。

只有一个执行方法。

package com.lyd.demo.command;

/**
* @Author: lyd
* @Description: 接口 - 命令
* @Date: 2022-09-03
*/
public interface Command {
public void execute(); // 执行方法
}

②、定义空命令

定义空命令是为了防止判空

package com.lyd.demo.command;
/**
* @Author: lyd
* @Description: 空命令方法,简化空判断
* @Date: 2022-09-03
*/
public class NoCommand implements Command {
@Override
public void execute() {
}
}

③、定义接受者

接收者就是具体的实现方法。

package com.lyd.demo.command.light;
/**
* @Author: lyd
* @Description: 被聚合类,也就是真正细节执行方法
* @Date: 2022-09-03
*/
public class LightReceive {
public void on() {
System.out.println(" 灯光已打开... ");
}
public void off() {
System.out.println(" 灯光已关闭... ");
}
}

④、定义实现类

灯光打开类,通过聚合方式获取具体实现方法;灯光实现类实现命令接口,实现执行方法(调用聚合类中的打开方法)

package com.lyd.demo.command.light;
import com.lyd.demo.command.Command;
/**
* @Author: lyd
* @Description: 实现类 - 点灯打开类
* @Date: 2022-09-03
*/
public class LightOnCommand implements Command {
// 聚合
LightReceive lightReceive;
public LightOnCommand(LightReceive lightReceive) {
this.lightReceive = lightReceive;
}
@Override
public void execute() { // 灯光打开命令只需要调用灯光开启的方法
lightReceive.on();
}
}

关闭命令也是如此设置,这里不粘贴代码了

⑤、定义遥控器

因为遥控器有许多设备的开关,定义相应开关按钮的命令组,通过构造方法去初始化,并把美格尔对象实例化为空命令对象。通过setCommand方法来绑定按钮和命令,onButton是模拟按下开关时候调用的方法。

package com.lyd.demo.controller;
import com.lyd.demo.command.Command;
import com.lyd.demo.command.NoCommand;
/**
* @Author: lyd
* @Description: 遥控器
* @Date: 2022-09-03
*/
public class RemoteController {
// 开按钮的命令组
Command[] onCommand;
// 关闭命令组
Command[] offCommand;
public RemoteController() { // 假设有舞台设备,每台设备都是开关命令
onCommand = new Command[5];
offCommand = new Command[5]; // 初始化
for (int i=0; i<5; i++) {
onCommand[i] = new NoCommand();
offCommand[i] = new NoCommand();
}
}
/**
* 给按钮设置命令
* @param no 编号-代表设备
* @param onCommand - 开命令
* @param offCommand - 关命令
*/
public void setCommand(int no, Command onCommand, Command offCommand) {
this.onCommand[no] = onCommand;
this.offCommand[no] = offCommand;
}
/**
* 按下开按钮
* @param no 根据编号去调用哪个设备的执行方法
*/
public void onButton(int no) {
onCommand[no].execute();
}
/**
* 按下关按钮
* @param no 根据编号去调用哪个设备的执行方法
*/
public void offButton(int no) {
offCommand[no].execute();
}
}

⑥、测试

以上介绍只是写了一种设备,还可以直接添加其他设备,并不需要改动其他类。

结构图:

代码如下:

package com.lyd.demo.test;

import com.lyd.demo.command.light.LightOffCommand;
import com.lyd.demo.command.light.LightOnCommand;
import com.lyd.demo.command.light.LightReceive;
import com.lyd.demo.command.tv.TvOffCommand;
import com.lyd.demo.command.tv.TvOnCommand;
import com.lyd.demo.command.tv.TvReceive;
import com.lyd.demo.controller.RemoteController; /**
* @Author: lyd
* @Description: 测试类
* @Date: 2022-09-03
*/
public class CommandTest {
public static void main(String[] args) {
// 创建灯光的接受者 - 具体方法类
LightReceive lightReceive = new LightReceive();
// 创建灯光的命令
LightOnCommand lightOnCommand = new LightOnCommand(lightReceive);
LightOffCommand lightOffCommand = new LightOffCommand(lightReceive);
// 创建遥控器
RemoteController remoteController = new RemoteController();
// 绑定命令到相应的按钮中
remoteController.setCommand(0, lightOnCommand, lightOffCommand); // 绑定
// 测试
System.out.println("按下开灯按钮》》》》》");
remoteController.onButton(0); // 0 代表是灯光按钮
System.out.println("按下关灯按钮》》》》》");
remoteController.offButton(0); TvReceive tvReceive = new TvReceive();
TvOnCommand tvOnCommand = new TvOnCommand(tvReceive);
TvOffCommand tvOffCommand = new TvOffCommand(tvReceive);
remoteController.setCommand(1, tvOnCommand, tvOffCommand);
System.out.println("按下开启电视按钮》》》》》");
remoteController.onButton(1);
System.out.println("按下关闭电视按钮》》》》》");
remoteController.offButton(1);
}
}

运行结果:

创作不易,可能有些语言不是很通畅,如有错误请指正,感谢观看!记得一键三连哦!

今天的内容看起来并不简单,但实质上除了设计模式的思路,其实就是Java的面向对象知识,只要肯动手多敲,就容易理解。

【设计模式】Java设计模式 - 命令模式的更多相关文章

  1. OOP设计模式[JAVA]——04命令模式

    命令模式 命令模式的意图 命令模式属于对象的行为模式.别名又叫:Action或Transaction. 命令模式把一个请求或者操作封装到一个对象中.命令模式允许系统使用不同的请求把客户端参数化,对请求 ...

  2. Java设计模式学习记录-命令模式

    前言 这次要介绍的是命令模式,这也是一种行为型模式.最近反正没有面试机会我就写博客呗,该投的简历都投了.然后就继续看书,其实看书也会给自己带来成就感,原来以前不明白的东西,书上已经给彻底的介绍清楚了, ...

  3. java 之 命令模式(大话设计模式)

    命令模式,笔者一直以为当我们开发的过程中基本上很难用到,直到维护阶段或者重构阶段,我们会发现有些撤销命令和追加命令比较频繁时,自然而然就用到命令模式. 先看下类图 大话设计模式-类图 简单说下类图,最 ...

  4. java设计模式-----23、命令模式

    概念: Command模式也叫命令模式 ,是行为设计模式的一种.Command模式通过被称为Command的类封装了对目标对象的调用行为以及调用参数. 命令模式(Command Pattern)是一种 ...

  5. 重学 Java 设计模式:实战命令模式「模拟高档餐厅八大菜系,小二点单厨师烹饪场景」

    作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 持之以恒的重要性 初学编程往往都很懵,几乎在学习的过程中会遇到 ...

  6. 《JAVA设计模式》之命令模式(Command)

    在阎宏博士的<JAVA与模式>一书中开头是这样描述命令(Command)模式的: 命令模式属于对象的行为模式.命令模式又称为行动(Action)模式或交易(Transaction)模式. ...

  7. Java设计模式系列之命令模式

    命令模式(Command)的定义 将一个请求封装为一个对象,从而可用不同的请求对客户进行参数化:对请求排队或记录日志,以及支持可撤销的操作,将”发出请求的对象”和”接收与执行这些请求的对象”分隔开来. ...

  8. JAVA设计模式之:命令模式

    *通常情况下:行为请求者与实现者通常呈现一种高度耦合状态.有时要对行为进行变更处理处理.高度耦合方式就显得不合适. * 将行为请求者与行为实现者解耦,将一组行为抽象为对象.实现二者之间的松耦合. 这就 ...

  9. JAVA设计模式之【命令模式】

    命令模式 为了降低耦合度,将请求的发送者和接收者解耦 发送请求的对象只需要哦知道如何发送请求,而不必知道如何完成请求 对请求排队 记录请求日志 支持撤销操作 核心在于引入命令类 角色 抽象命令类Com ...

  10. Java设计模式(20):命令模式

    本文源码:GitHub·点这里 || GitEE·点这里 一.生活场景 1.场景描述 智能电脑的品牌越来越多,由此诞生了一款电脑控制的APP,万能遥控器,用户在使用遥控器的时候,可以切换为自家电视的品 ...

随机推荐

  1. GIS技术在医疗行业的应用:利用切片地图发布技术解决dmetrix数字病理切片在线浏览

    最近一直在研究切片地图发布技术,解决各种矢量和栅格数据的切片地图制作和发布问题.这块的技术在土地评估和调查类公司中应用较多,因为他们经常需要使用各地地图,传统的文件管理方式很难适应工作现状,如果将各种 ...

  2. Redis相关练习操作,redis连接池

    package com.shujia.controller; import com.shujia.entity.MyTypedTuple; import com.shujia.entity.User; ...

  3. 【每天学一点-02】创建Node.js的第一个应用

    1.引入require模块,使用createServer()创建服务器 [server.js]文件 var http = require('http'); http.createServer(func ...

  4. C++中关于cout相关的输出格式(操作流算子)

    这边需要注意的是如果使用到setpercision,一定要引入iomanip头文件,否则编译会出错 注意以下的操作流算子都是在头文件iomanip中定义的,强烈建议使用的时候引入改头文件否则可能会出现 ...

  5. 从零开始在centos搭建博客(一)

    本篇为安装篇. 基于centos 7.9,大部分东西使用docker安装. 软件列表:docker + mysql + wordpress 安装docker yum install -y yum-ut ...

  6. java 向上,向下取整详解

    向上取整函数:Math.ceil(double a); 向下取整函数:Math.floor(double a); 需要注意的是:取整是对小数的取整,由于java自动转型机制,两个整数的运算结果依然是整 ...

  7. Thingsboard硬网关金鸽BL102采集三菱PLC步骤

    PLC网关金鸽BL102:采集三菱FX-5U数据如何转成MQTT上报?金鸽BL102PLC网关时一款功能强大的PLC数据采集网关,南向可以采集主流的PLC,如三菱.西门子.台达.欧姆龙.施耐德等等PL ...

  8. 有事务冲突时节点怎么加入MGR集群

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 目录 1. 问题场景描述 2. 如何修复 2.1 找出事务差异点 2.2 决定如何处理 3. 小结 文章推荐: 关于 Gr ...

  9. 【转载】一封面向社会,关于对近日来 CCF 不当行为之抗议的公开信

    原文链接:https://101001011.github.io/2022/06/11/zhi-ccf-de-yi-feng-gong-kai-xin/ 原文作者:CCA(CCA's Blog) 前天 ...

  10. django中的forms组件

    form介绍 用户需要向后端提交一些数据时,我们常常把这些数据放在一个form表单里,采用form标签,里面包含一些input等标签把用户的数据提交给后端. 在给后端提交数据的时候,我们常常也需要对于 ...