java 设计模式之命令模式(十三)
作者:互联网
java 设计模式之命令模式①三
人生只能在路上,梦想只能在前方,有心无难事,有诚路就定通,正确的心态能让你的人生更坦然舒心。当然,心态是依靠你自己调整的,只要你愿意,你就可以给自己的一个正确的心态,只要你愿意,你就可以坚持下去。
定义
在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。但在某些场合,比如要对行为进行“记录、撤销/重做、事务”等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将“行为请求者”与“行为实现者”解耦?将一组行为抽象为对象,实现二者之间的松耦合。这就是命令模式(Command Pattern)
命令模式分析
- 命令模式的本质是对命令进行封装,将发出命令的责任和执行命令的责任分割开。
- 每一个命令都是一个操作:请求的一方发出请求,要求执行一个操作;接收的一方收到请求,并执行操作。
- 命令模式允许请求的一方和接收的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求是怎么被接收,以及操作是否被执行、何时被执行,以及是怎么被执行的。
- 命令模式使请求本身成为一个对象,这个对象和其他对象一样可以被存储和传递。
- 命令模式的关键在于引入了抽象命令接口,且发送者针对抽象命令接口编程,只有实现了抽象命令接口的具体命令才能与接收者相关联。
简单理解:
要去打仗,将军发布命令 士兵执行命令 将军不会直接和士兵打交道,通过命令来 ‘连接’ 将军和士兵
角色分析
- ICommand 用来定义命令接口
- Soldiers 指士兵 实现ICommand命令接口
- Admiral 指将军 聚合了ICommand命令接口,用来发送命令
- CommandContent 指命令具体内容
UML类图(1.1)
:
项目需求
比如说现在家里有:
- 电脑
- 电视
- 手机
- 空调
等家电,每个家电都对应一个遥控器,比如这里有4种家电,那么就要对应4种遥控器,非常的麻烦,命令模式就可以将这4种家电把它组合成一个遥控器,可以用一个遥控器来控制这4种家电.像这样
效果图(2.1)
:
通过遥控器发送命令,然对应的产品实现对应的功能,比如说点击电视打开按钮,就打开电视等操作
代码实现
ICommand(命令接口):
public interface ICommand {
//开始
public void start();
//撤回
public void withdraw();
}
CommandContent(命令具体内容):
public class CommandContent {
String type;
//传递的是家电 比如说电视
public CommandContent(String type) {
this.type = type;
}
public void on(){
Log.i("命令模式",type+" 打开了~ ");
}
public void off(){
Log.i("命令模式",type+" 关闭了~ ");
}
}
TvOffCommand,具体实现接口(电视关闭):
public class TvOffCommand implements ICommand{
CommandContent dispatchOrders;
public TvOffCommand(CommandContent dispatchOrders) {
this.dispatchOrders = dispatchOrders;
}
@Override
public void start() {
//如果点击关闭,执行关闭命令
dispatchOrders.off();
}
@Override
public void withdraw() {
//点击撤销,执行打开命令
dispatchOrders.on();
}
}
TvOnCommand ,具体实现接口(电视打开):
public class TvOnCommand implements ICommand{
CommandContent dispatchOrders;
public TvOnCommand(CommandContent dispatchOrders) {
this.dispatchOrders = dispatchOrders;
}
@Override
public void start() {
//如果点击打开,执行打开命令
dispatchOrders.on();
}
@Override
public void withdraw() {
//点击撤销,执行关闭命令
dispatchOrders.off();
}
}
NoCommand(空命令,用来第一次初始化,因为第一次既不是打开也不是关闭 ):
public class NoCommand implements ICommand{
@Override
public void start() {
}
@Override
public void withdraw() {
}
}
CallCommand(命令调用者):
public class CallCommand {
//开命令
ICommand[] tvOnCommand;
//关命令
ICommand[] tvOffCommand;
//记录当前存放的命令 用来撤回
ICommand currentCommand;
//默认可存放5条命令
int number = 5;
//初始化命令
public CallCommand() {
tvOnCommand = new ICommand[number];
tvOffCommand = new ICommand[number];
for (int i = 0; i < number; i++) {
//先默认为空的命令
tvOnCommand[i] = new NoCommand();
tvOffCommand[i] = new NoCommand();
}
}
/**
* @param index 当前存放的下标
* @param OnCommand 开始下标
* @param OffCommand 结束下标
*/
public void setTvOnCommand(int index, ICommand OnCommand, ICommand OffCommand) {
this.tvOnCommand[index] = OnCommand;
this.tvOffCommand[index] = OffCommand;
}
/**
* @param index 命令下标
*/
public void getOnCommand(int index) {
this.tvOnCommand[index].start();
//记录当前命令
currentCommand = this.tvOnCommand[index];
}
/**
* @param index 命令下标
*/
public void getOffCommand(int index) {
this.tvOffCommand[index].start();
//记录当前命令
currentCommand = this.tvOffCommand[index];
}
/**
* 撤回
*/
public void getWithdraw() {
currentCommand.withdraw();
}
}
测试代码(客户端):
//创建打开电视机命令具体内容
CommandContent commandContent1 = new CommandContent("电视机");
//初始化电视机开关命令
TvOnCommand tvOnCommand = new TvOnCommand(commandContent1);
TvOffCommand tvOffCommand = new TvOffCommand(commandContent1);
//创建遥控器
CallCommand callCommand = new CallCommand();
//给遥控器初始化电视机开关命令
callCommand.setTvOnCommand(0,tvOnCommand,tvOffCommand);
//调用遥控器打开命令
callCommand.getOnCommand(0);
//调用遥控器关闭命令
callCommand.getOffCommand(0);
//调用遥控器撤回命令
callCommand.getWithdraw();
Log图(3.1)
:
优点:
- 降低对象之间的耦合度。
- 新的命令可以很容易地加入到系统中。
- 准守了开闭原则(对扩展开放,对修改关闭),能够很好的扩展
缺点:
- 如果是简单的功能会造成代码很多,类很多,不懂命令模式的话会造成阅读苦难.
- 针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。
如何进行扩展
假设现在需要添加手机开关的命令:
PhoneOnCommand(手机打开命令):
public class PhoneOnCommand implements ICommand{
CommandContent dispatchOrders;
public PhoneOnCommand(CommandContent dispatchOrders) {
this.dispatchOrders = dispatchOrders;
}
@Override
public void start() {
dispatchOrders.on();
}
@Override
public void withdraw() {
dispatchOrders.off();
}
}
PhoneOffCommand (手机关闭命令):
public class PhoneOffCommand implements ICommand{
CommandContent dispatchOrders;
public PhoneOffCommand(CommandContent dispatchOrders) {
this.dispatchOrders = dispatchOrders;
}
@Override
public void start() {
dispatchOrders.off();
}
@Override
public void withdraw() {
dispatchOrders.on();
}
}
测试代码(客户端):
//创建命令具体类容
CommandContent commandContent2 = new CommandContent("手机");
//创建手机命令
PhoneOnCommand phoneOnCommand = new PhoneOnCommand(commandContent2);
PhoneOffCommand phoneOffCommand = new PhoneOffCommand(commandContent2);
//设置给遥控器命令
callCommand.setTvOnCommand(1,phoneOnCommand,phoneOffCommand);
//遥控器打开手机
callCommand.getOnCommand(1);
//遥控器关闭手机
callCommand.getOffCommand(1);
//遥控器打开手机
callCommand.getOnCommand(1);
//遥控器撤销
callCommand.getWithdraw();
Log图(3.2)
:
可以看出,没有改原始代码,只是修改了一下’命令’,依然可以调到对应的方法;
原创不易,您的点赞就是对我最大的支持~
标签:ICommand,java,dispatchOrders,十三,void,命令,CommandContent,设计模式,public 来源: https://blog.csdn.net/weixin_44819566/article/details/112714972