热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java设计模式(16):命令模式

16,命令模式(Command)16.1,问题引入_智能生活项目需求假如有一套智能家电,照明灯、风扇、空调
16,命令模式(Command)

16.1,问题引入_智能生活项目需求


  • 假如有一套智能家电,照明灯、风扇、空调、冰箱、洗衣机等,需要在手机上安装APP进行控制
  • 这些智能家电来自不同的厂家,每一个厂家针对设备都有不同的APP,但是我们不想下载那么多的APP,希望通过一个APP进行全控制,如万能遥控
  • 要实现一个APP控制所有智能家电的需要,则各个智能家电需要一个统一的接口提供给APP使用,这时候可以考虑命令模式
  • 命令模式可以将 动作的请求者动作的执行者 对象中解耦出来
  • 在这个例子中:动作的请求者是手机APP,动作的执行者就是各个智能家电

16.2,基本介绍


  • 命令模式(Command Pattern):在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道请求的操作是哪个,我们只需要在程序运行时指定具体的请求接收者即可。此时,可以使用命令模式设计
  • 命令模式使得请求发送者和请求接收者消除彼此之间的耦合,让对象间的调用关系更加灵活,实现解耦
  • 命令模式中,会将一个请求封装为一个对象,使用不同的参数来表示不同的请求,同时命令模式也支持撤销操作
  • 用一个简单的解释:将军发送命令,士兵去执行。其中将军就是请求发送者,士兵是请求接收者,命令连接了将军和士兵
  • 命令模式在 Spring 框架中的 JDBCTemplate 模块中有被使用,StatementCallBack 接口是命令顶层接口

16.3,类图

在这里插入图片描述

  • Light:请求接收者,真正执行命令的角色,控制运行
  • Command:命令,也就是请求发送者和请求接收者的关联角色,知道如果实施和执行一个指令操作
  • LightXXCommand:具体命令角色,实现自 Command,将一个命令与一个功能绑定,通过命令实现功能
  • RemoteController:请求发送者,即APP万能遥控,通过按钮实现功能控制。每一个命令角色封装,对万能遥控的呈现即为一个按钮
  • Client:客户端,即操作人,通过APP进行控制

16.4,代码实现


  • Light:请求接收者,具体执行类

    package com.self.designmode.command;/*** 请求接收者: 具体工作类* @author PJ_ZHANG* @create 2020-12-10 13:52**/
    public class Light {public void on() {System.out.println("电灯打开了...");}public void off() {System.out.println("电灯关上了...");}}

  • Command:顶层命令接口,连接请求发起者和请求接收者

    package com.self.designmode.command;/*** 命令顶层接口* @author PJ_ZHANG* @create 2020-12-10 13:50**/
    public interface Command {/*** 执行操作*/void execute();/*** 撤销操作*/void undo();}

  • LightOnCommand:具体命令类,实际调度请求接收者的功能

    package com.self.designmode.command;/*** 具体命令, 对应某种功能* 打开电灯* @author PJ_ZHANG* @create 2020-12-10 13:54**/
    public class LightOnCommand implements Command {private Light light;public LightOnCommand(Light light) {this.light = light;}@Overridepublic void execute() {light.on();}@Overridepublic void undo() {light.off();}
    }

  • LightOffCommand:具体命令类,实际调度请求接收者的功能

    package com.self.designmode.command;/*** 具体命令, 对应某种功能* 关闭电灯* @author PJ_ZHANG* @create 2020-12-10 13:54**/
    public class LightOffCommand implements Command {private Light light;public LightOffCommand(Light light) {this.light = light;}@Overridepublic void execute() {light.off();}@Overridepublic void undo() {light.on();}
    }

  • NoCommand:命令空实现,作为预留部分

    package com.self.designmode.command;/*** @author PJ_ZHANG* @create 2020-12-10 14:02**/
    public class NoCommand implements Command {@Overridepublic void execute() {System.out.println("do nothing,,,");}@Overridepublic void undo() {System.out.println("do nothing,,,");}}

  • RemoteController:请求发起者,即万能遥控

    package com.self.designmode.command;import java.util.HashMap;
    import java.util.Map;/*** 请求发起者, 即万能遥控,* @author PJ_ZHANG* @create 2020-12-10 13:55**/
    public class RemoteController {private Map<String, Command> onCommandMap &#61; new HashMap<>(16);private Map<String, Command> offCommandMap &#61; new HashMap<>(16);private Command undoCommand;/*** 初始化开关* &#64;param type* &#64;param onCommand* &#64;param offCommand*/public void setCommand(String type, Command onCommand, Command offCommand) {onCommandMap.put(type, onCommand);offCommandMap.put(type, offCommand);}/*** 打开开关命令* &#64;param type*/public void onCommand(String type) {Command onCommand &#61; null &#61;&#61; onCommandMap.get(type) ? new NoCommand() : onCommandMap.get(type);onCommand.execute();undoCommand &#61; onCommand;}/*** 关闭开关命令* &#64;param type*/public void offCommand(String type) {Command offCommand &#61; null &#61;&#61; offCommandMap.get(type) ? new NoCommand() : offCommandMap.get(type);offCommand.execute();undoCommand &#61; offCommand;}/*** 撤销开关命令*/public void undoCommand() {undoCommand.undo();}}

  • Client&#xff1a;客户端&#xff0c;用户操作

    package com.self.designmode.command;/*** 客户端操作* &#64;author PJ_ZHANG* &#64;create 2020-12-10 14:09**/
    public class Client {public static void main(String[] args) {// 初始化请求接收者,即实际执行类Light light &#61; new Light();// 初始化具体命令类,即命令Command lightOnCommand &#61; new LightOnCommand(light);Command lightOffCommand &#61; new LightOffCommand(light);// 初始化遥控器, 即请求发起者RemoteController remoteController &#61; new RemoteController();// 绑定命令remoteController.setCommand("1", lightOnCommand, lightOffCommand);// 开灯remoteController.onCommand("1");// 关灯remoteController.offCommand("1");// 撤销remoteController.undoCommand();// 如果需要添加其他智能家居,// 只需要添加请求接收者和对应的具体命令类// 在初始化遥控器时设置为不同的type即可}}


16.5&#xff0c;命令模式的注意事项和细节


  • 将发起请求的对象和执行请求的对象解耦。发起请求的对象是调用者&#xff0c;调用者只需要调用命令对象的 execute() 方法可以让接口者工作&#xff0c;而不必知道接收者是谁、是如何工作的。命令对象会负责让对应的接收者执行工作。也就是说 请求发起者请求接受者 是完全解耦的&#xff0c;命令对象在中间起连接作用
  • 比较容易的设计一个命令队列。只需要将命令放入队列中&#xff0c;就可以进行多线程控制
  • 比较容易的实现对请求的撤销和重做
  • 空命令也是命令模式的一种设计&#xff0c;省去了判空操作&#xff0c;对命令进行了基础的空实现
  • 命令模式的应用场景&#xff1a;界面的一个按钮都是一个命令&#xff0c;模拟基于命令的订单撤销、恢复、触发、反馈机制
  • 命令模式不足&#xff1a;可能导致某些系统有过多的具体命令类&#xff0c;增加系统复杂性

推荐阅读
  • Spring学习(4):Spring管理对象之间的关联关系
    本文是关于Spring学习的第四篇文章,讲述了Spring框架中管理对象之间的关联关系。文章介绍了MessageService类和MessagePrinter类的实现,并解释了它们之间的关联关系。通过学习本文,读者可以了解Spring框架中对象之间的关联关系的概念和实现方式。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • 重入锁(ReentrantLock)学习及实现原理
    本文介绍了重入锁(ReentrantLock)的学习及实现原理。在学习synchronized的基础上,重入锁提供了更多的灵活性和功能。文章详细介绍了重入锁的特性、使用方法和实现原理,并提供了类图和测试代码供读者参考。重入锁支持重入和公平与非公平两种实现方式,通过对比和分析,读者可以更好地理解和应用重入锁。 ... [详细]
  • 解决.net项目中未注册“microsoft.ACE.oledb.12.0”提供程序的方法
    在开发.net项目中,通过microsoft.ACE.oledb读取excel文件信息时,报错“未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序”。本文提供了解决这个问题的方法,包括错误描述和代码示例。通过注册提供程序和修改连接字符串,可以成功读取excel文件信息。 ... [详细]
  • Java SE从入门到放弃(三)的逻辑运算符详解
    本文详细介绍了Java SE中的逻辑运算符,包括逻辑运算符的操作和运算结果,以及与运算符的不同之处。通过代码演示,展示了逻辑运算符的使用方法和注意事项。文章以Java SE从入门到放弃(三)为背景,对逻辑运算符进行了深入的解析。 ... [详细]
  • 代理模式的详细介绍及应用场景
    代理模式是一种在软件开发中常用的设计模式,通过在客户端和目标对象之间增加一层中间层,让代理对象代替目标对象进行访问,从而简化系统的复杂性。代理模式可以根据不同的使用目的分为远程代理、虚拟代理、Copy-on-Write代理、保护代理、防火墙代理、智能引用代理和Cache代理等几种。本文将详细介绍代理模式的原理和应用场景。 ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • 本文介绍了一个Java猜拳小游戏的代码,通过使用Scanner类获取用户输入的拳的数字,并随机生成计算机的拳,然后判断胜负。该游戏可以选择剪刀、石头、布三种拳,通过比较两者的拳来决定胜负。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了在Java中gt、gtgt、gtgtgt和lt之间的区别。通过解释符号的含义和使用例子,帮助读者理解这些符号在二进制表示和移位操作中的作用。同时,文章还提到了负数的补码表示和移位操作的限制。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
author-avatar
he小任a
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有