《Head First设计模式》之命令模式

2024-09-03 00:32

本文主要是介绍《Head First设计模式》之命令模式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

    命令模式就是将方法调用(Method invocation)封装起来。通过封装方法调用,我们可以把运算块包装成形,所以调用此运算的对象不需要关心事情是如何进行的,只要知道如何使用包装成形的方法来完成它就可以了。通过封装方法调用,可以用在以下场景:记录日志或者重复使用这些封装来实现撤销(undo)。

    我对于命令模式的理解是:当我需要做一件事的时候,我只需要给出一个命令,这个命令中的具体事情是如何实现的,与我无关,具体实现也不是我负责。我只要封装好你的具体实现就行。然后发出我的命令,调用你的实现,最后完成我的命名。每个命令模式的提出,肯定是为了解决某种场景下的代码耦合,而命令模式的提出是为了解决命令的请求者和命令的实现者之间的解耦。对于这类解耦的好处:我还没想的特别清楚。

    举个例子来分析下命令模式在实际生活中的实现场景。比如说有一家餐馆,有一个顾客,有一个服务员,有一个厨师。顾客进去吃饭,会填写一份菜单,交给服务员,服务员把菜单交给厨师,由厨师做出顾客需要的菜。在这个场景中,顾客是命令的发出者,发出的命令就是那份菜单,服务员只是命令的接收者,厨师才是命令的具体实现者。下面开始我会贴出集体的代码,github地址是:https://github.com/fishingfly/DesignPatternCode。

下面就是代码例子:

命令就是LightOnCommand

命令中动作的具体实现者就是Light

命令的发出者就是RemoteLoader

命令的接收者是RemoteControl

来看看具体代码:

     Command为所有命令声明了一个接口,调用命令对象的execute()方法,就可以让接收者进行相关的动作。

public interface Command {public void execute();
}

    LightOnCommand实现execute()方法,在这个方法中会调用接收者的动作。

/*** @Auther: user* @Date: 2019/1/18 17:14* @Description:*/
public class LightOnCommand implements Command {private Light light;public LightOnCommand(Light light) {this.light = light;}@Overridepublic void execute() {light.on();}
}

       Light类就是一个功能类,也就是命令中某些动作的具体实现者

/*** @Auther: user* @Date: 2019/1/18 17:12* @Description:*/
public class Light {/*** @Description: 打开灯开关* @param* @return* @throws* @author user* @date 2019/1/18 17:13*/public void on() {System.out.println("灯亮了");}/*** @Description: 关闭灯开关* @param* @return* @throws* @author user* @date 2019/1/18 17:13*/public void off() {System.out.println("灯灭了");}
}

RemoteControl这个就是命令接收的地方,命令发出者会将命令发送给RemoteControl,由RemoteControl类调用命令的execute方法来完成命令:

/*** @Auther: user* @Date: 2019/1/18 17:18* @Description:*/
public class RemoteControl {Command [] onCommands;Command [] offCommands;public RemoteControl() {onCommands = new Command[7];offCommands = new Command[7];Command noCommand = new NoCommand();for (int i = 0; i < 7; i++) {onCommands[i] = noCommand;offCommands[i] = noCommand;}}public void setCommand(int slot, Command onCommand, Command offCommand) {onCommands[slot] = onCommand;offCommands[slot] = offCommand;}public void onButtonWasPushed(int slot) {onCommands[slot].execute();}public void offButtonWasPushed(int slot) {offCommands[slot].execute();}}

RemoteLoader就是命令的请求者了,他是发出命令的人:

/*** @Auther: user* @Date: 2019/1/18 17:29* 命令模式可以用于日志和队列中。* @Description:*/
public class RemoteLoader {public static void main(String[] args) {RemoteControl remoteControl = new RemoteControl();Light light = new Light();remoteControl.setCommand(0,new LightOnCommand(light), new LightOffCommand(light));remoteControl.offButtonWasPushed(0);remoteControl.onButtonWasPushed(0);}
}

整个命令模式到这边就结束了。

   命令模式可以用于队列请求,日志请求和实现撤销操作等。队列请求,想象一个工作队列,你在某一端添加命令,然后另一端则是线程,线程进行下面的动作:从队列中取出一个命令,调用它的execute方法,等待这个调用完成,然后将此命令对象丢弃,再取出下一个命令。

   日志请求:某些应用需要我们将所有的动作都记录在日志中,并能在系统死机之后,重新调用这些动作恢复到之前的状态,通过新增两个方法马(store(),load()),命令模式就能够支持这一点。在java中,我们可以利用对象的序列化实现这些方法,但是一般认为序列化最好还是只用在对象的持久化上。当我们执行命令的时候,讲历史纪录存储在磁盘上,一旦系统死机,我们就可以将命令对象重新加载,并成批地依次调用这些对象的execute()方法上。也可以用在事务上。

    记一下命令模式的要点:

1、命令模式将请求封装成对象,这可以让你使用不同的请求,队列或者日志请求来参数化奇特对象。

2、命令模式将发出请求的对象和执行请求的对象解耦。

3、在被解耦的两者之间是通过命令对象进行沟通的,命令对象封装了接收者和一个或者一组动作。

4、调用者通过调用命令对象的execute()方法发出请求,这会使得接收者的动作会被调用。

5、调用者可以接受命令当作参数,升值在运行时动态地进行。

6、实际操作时,很常见使用“聪明”命令对象,也就是直接实现了请求,而不是将工作委托给接收者。

 

 

 

 

这篇关于《Head First设计模式》之命令模式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

Java -jar命令如何运行外部依赖JAR包

《Java-jar命令如何运行外部依赖JAR包》在Java应用部署中,java-jar命令是启动可执行JAR包的标准方式,但当应用需要依赖外部JAR文件时,直接使用java-jar会面临类加载困... 目录引言:外部依赖JAR的必要性一、问题本质:类加载机制的限制1. Java -jar的默认行为2. 类加

git stash命令基本用法详解

《gitstash命令基本用法详解》gitstash是Git中一个非常有用的命令,它可以临时保存当前工作区的修改,让你可以切换到其他分支或者处理其他任务,而不需要提交这些还未完成的修改,这篇文章主要... 目录一、基本用法1. 保存当前修改(包括暂存区和工作区的内容)2. 查看保存了哪些 stash3. 恢

java -jar命令运行 jar包时运行外部依赖jar包的场景分析

《java-jar命令运行jar包时运行外部依赖jar包的场景分析》:本文主要介绍java-jar命令运行jar包时运行外部依赖jar包的场景分析,本文给大家介绍的非常详细,对大家的学习或工作... 目录Java -jar命令运行 jar包时如何运行外部依赖jar包场景:解决:方法一、启动参数添加: -Xb

RabbitMQ工作模式中的RPC通信模式详解

《RabbitMQ工作模式中的RPC通信模式详解》在RabbitMQ中,RPC模式通过消息队列实现远程调用功能,这篇文章给大家介绍RabbitMQ工作模式之RPC通信模式,感兴趣的朋友一起看看吧... 目录RPC通信模式概述工作流程代码案例引入依赖常量类编写客户端代码编写服务端代码RPC通信模式概述在R

Linux基础命令@grep、wc、管道符的使用详解

《Linux基础命令@grep、wc、管道符的使用详解》:本文主要介绍Linux基础命令@grep、wc、管道符的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录grep概念语法作用演示一演示二演示三,带选项 -nwc概念语法作用wc,不带选项-c,统计字节数-

MySQL的ALTER TABLE命令的使用解读

《MySQL的ALTERTABLE命令的使用解读》:本文主要介绍MySQL的ALTERTABLE命令的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、查看所建表的编China编程码格式2、修改表的编码格式3、修改列队数据类型4、添加列5、修改列的位置5.1、把列

SQL Server身份验证模式步骤和示例代码

《SQLServer身份验证模式步骤和示例代码》SQLServer是一个广泛使用的关系数据库管理系统,通常使用两种身份验证模式:Windows身份验证和SQLServer身份验证,本文将详细介绍身份... 目录身份验证方式的概念更改身份验证方式的步骤方法一:使用SQL Server Management S

Redis高可用-主从复制、哨兵模式与集群模式详解

《Redis高可用-主从复制、哨兵模式与集群模式详解》:本文主要介绍Redis高可用-主从复制、哨兵模式与集群模式的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录Redis高可用-主从复制、哨兵模式与集群模式概要一、主从复制(Master-Slave Repli

一文带你搞懂Redis Stream的6种消息处理模式

《一文带你搞懂RedisStream的6种消息处理模式》Redis5.0版本引入的Stream数据类型,为Redis生态带来了强大而灵活的消息队列功能,本文将为大家详细介绍RedisStream的6... 目录1. 简单消费模式(Simple Consumption)基本概念核心命令实现示例使用场景优缺点2

Nginx location匹配模式与规则详解

《Nginxlocation匹配模式与规则详解》:本文主要介绍Nginxlocation匹配模式与规则,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、环境二、匹配模式1. 精准模式2. 前缀模式(不继续匹配正则)3. 前缀模式(继续匹配正则)4. 正则模式(大