Java设计模式之命令模式详解
作者:在下木子李 发布时间:2023-11-15 21:18:43
标签:Java,命令模式,设计模式
命令模式
定义:将请求封装成对象,这可以让你使用不同的请求、队列、或者日志来参数化其他对象。
何时使用命令模式?当需要将发出请求的对象和执行请求的对象解耦的时候,使用命令模式。
在被解耦的两者之间是通过命令对象进行沟通的。命令对象封装了接收者和一个或一组动作。
调用者通过调用命令对象的execute()方法发出请求,这会使接收者的动作被调用。
调用者可以接收命令当作参数,甚至在运行时动态地进行。
优点:
1、降低了系统耦合度。
2、新的命令可以很容易添加到系统中去。
缺点:使用命令模式可能会导致某些系统有过多的具体命令类。
实现案例
需求:实现一个遥控器类,遥控器有多组开/关按钮,每组按钮控制一个电器对象的开和关。使用命令模式实现整个功能。
1、创建命令接口
package com.example.designpatternsdemo.commandPattern;
/**
* 命令接口
*/
public interface Command {
public void execute();
}
2、创建电灯、电视类(命令接收者)
package com.example.designpatternsdemo.commandPattern;
/**
* 电灯
*/
public class Light {
//on/off动作
public void on(){
System.out.println("开启电灯");
}
public void off(){
System.out.println("关闭电灯");
}
}
package com.example.designpatternsdemo.commandPattern;
/**
* 电视
*/
public class TV {
public void on(){
System.out.println("开启电视");
}
public void off(){
System.out.println("关闭电视");
}
}
3、创建具体命令类
package com.example.designpatternsdemo.commandPattern;
/**
* 开启电灯命令类
*/
public class LightOnCommand implements Command{
//电灯对象
private Light mLight;
public LightOnCommand(Light light){
this.mLight = light;
}
@Override
public void execute() {
mLight.on();
}
}
package com.example.designpatternsdemo.commandPattern;
/**
* 关闭电灯命令类
*/
public class LightOffCommand implements Command{
//电灯对象
private Light mLight;
public LightOffCommand(Light light){
this.mLight = light;
}
@Override
public void execute() {
mLight.off();
}
}
这里省略电视的开关命令类
4、创建遥控器类
package com.example.designpatternsdemo.commandPattern;
/**
* 命令调用者
* 遥控器
*/
public class RemoteControl {
//保存开关命令对象的数组
Command[] onCommands;
Command[] offCommands;
public RemoteControl(){
//初始化数组
onCommands = new Command[2];
offCommands = new Command[2];
}
//存储命令
public void setCommand(int index,Command onCommand,Command offCommand){
onCommands[index] = onCommand;
offCommands[index] = offCommand;
}
//开按钮
public void onButtonPress(int btnIndex){
onCommands[btnIndex].execute();
}
//关按钮
public void offButtonPress(int btnIndex){
offCommands[btnIndex].execute();
}
}
5、创建客户类(测试类)
package com.example.designpatternsdemo.commandPattern;
public class Client {
public static void main(String[] args) {
//创建电灯对象(命令接收者)
Light myLight = new Light();
//创建电灯开关命令对象
LightOnCommand lightOnCommand = new LightOnCommand(myLight);
LightOffCommand lightOffCommand = new LightOffCommand(myLight);
//创建遥控器对象(命令调用者)
RemoteControl remoteControl = new RemoteControl();
//设置命令
remoteControl.setCommand(0,lightOnCommand,lightOffCommand);
//发起命令执行请求
remoteControl.onButtonPress(0);
remoteControl.offButtonPress(0);
TV myTv = new TV();
TvOnCommand tvOnCommand = new TvOnCommand(myTv);
TvOffCommand tvOffCommand = new TvOffCommand(myTv);
remoteControl.setCommand(1,tvOnCommand,tvOffCommand);
remoteControl.onButtonPress(1);
remoteControl.offButtonPress(1);
}
}
将开/关电灯、电视的请求封装成命令类对象,在类中的execute()方法调用具体电灯/电视的开关动作,调用时,遥控器类(命令调用者)只需调用具体某个命令对象的execute()方法,那他就会通知具体的电器来执行动作,这样,就实现了命令调用者和执行者之间的解耦。调用者不需要知道是谁执行动作,只需要调用命令对象的execute()方法去通知执行就可以。
来源:https://blog.csdn.net/weixin_44902943/article/details/116118136


猜你喜欢
- 碎片,它的出现是为了更好展示UI的设计,让程序更加得到充分的展示。Fragment的出现,如微信的额主界面包含多个Fragment,使得微信
- 1.企业实际项目中Git的使用在实际的企业项目开发中,我们一般Java的项目在公司都有自己的局域网代码仓库,仓库上存放着很多的项目。以我工作
- 最好使用英文,不要用汉语拼音1:包(package):用于将完成不同功能的类分门别类,放在不同的目录(包)下,包的命名规则:将公司域名反转作
- public static Expression<Func<T, bool>> GetSearchExpressio
- package com.test; import java.io.FileNotFoundException;&nbs
- @RequestParam设置默认可以传空值设置如下@RequestParam(value="CbqkJson[]",r
- 发现问题需求很简单,大致就是要批量往数据库写数据,于是打算用Parallel并行的方式写入,希望能利用计算机多核特性加快程序执行速度。想的很
- 本文实例讲述了C#之Expression表达式树,分享给大家供大家参考。具体实现方法如下:表达式树表示树状数据结构的代码,树状结构中的每个节
- 上一章节回顾:Netty分布式源码分析监听读事件概述pipeline, 顾名思义, 就是管道的意思, 在net
- 关于约瑟夫环的基本知识:罗马人攻占了乔塔帕特,41人藏在一个山洞中躲过了这场浩劫。这41个人中,包括历史学家josephus和他的一个朋友。
- 在构建RESTful数据服务过程中,我们定义了controller、repositories,并用一些注解修饰它们,但是到现在为止我们还没执
- 摘要:本文演示如何构建起一个优秀的后端接口体系,体系构建好了自然就有了规范,同时再构建新的后端接口也会十分轻松。一个后端接口大致分为四个部分
- 一、引言在刷算法的时候经常需要对数组进行排序,第一反应就是直接使用java.util包下的Arrays.sort()方法直接排序。但在刷算法
- dynamic是FrameWork4.0的新特性。dynamic的出现让C#具有了弱语言类型的特性。编译器在编译的时候不再对类型进行检查,编
- 背景现行的文本编辑器大多都具备文本查询的能力,但是并不能直观的告诉用户两段文字的细微差异,所以对比工具在某种情况下,就起到了很便捷的效率。关
- ThreadLocal 看名字 就可以看出一点头绪来,线程本地。来看一下java对他的描述:该类提供线程本地变量。这些变量与它们的正常对应变
- 这篇文章首先介绍了在SpringBoot中如何获得项目的编译时间和版本号,并向外提供接口,然后介绍了介绍了新版maven获得时间戳时区错误的
- Struts2简介Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts
- 先给大家展示下效果图,如果大家感觉还不错,请参考实现代码很简单的一个例子,点击刷新验证码,刷新当前显示的验证码,点击确定,如果输入的和显示的
- 一、VSCode安装EmmyLua 二、添加配置文件三、设置配置文件执行完第二步会弹出添加好的launch.json配置文件,这个