写在前面
本文看下命令设计模式。
1:介绍
1.1:什么时候使用命令设计模式
如果某个对象依赖于外部传入的具体参数来执行具体的操作时,就可以考虑使用命令设计模式,如空调的制冷,制热,小爱同学的唱歌,讲笑话等,都是通过外部的具体指令发生的操作。
1.2:UML类图
原型设计模式,包含如下元素:
1:Receiver负责执行具体指令的类,即能够执行特定操作的类
2:Command命令抽象,内部维护Receiver,通过Recevier让命令最终变成具体的动作
3:Invoker维护一组Command,并执行这组指令
4:客户端负责创建Invoker,并设置相关需要执行的指令
2:实例
源码 。
2.1:场景
小明家里有一台空调,可以控制其制冷和制热,有一个小爱同学,可以控制其唱歌🎤和讲笑话。
2.2:程序
- 定义空调Receiver
// 空调
public class AirConditionerReceiver {// 制冷public void cold() {System.out.println("空调制冷了");}// 制热public void hot() {System.out.println("空调制热了");}
}
- 定义小爱同学Receiver
// 小爱同学
public class XiaoAiTongXueReceiver {// 唱歌public void sing() {System.out.println("小爱同学唱歌了");}// 讲笑话public void joke() {System.out.println("小爱同学讲笑话了");}
}
接着我们来定义用来执行空调制冷,空调制热,小爱同学唱歌,小爱同学讲笑话的Command类,首先定义接口:
// 命令的抽象,
public interface Command {void exec();
}
- 各种执行具体动作的Command
一共四个,分别是执行空调制冷的Command,空调制热的Command,小爱同学唱歌的Command,小爱同学讲笑话的Command,如下:
// 制冷命令,内部调用空调的制冷操作
public class ColdCommand implements Command {private AirConditionerReceiver receiver;public ColdCommand(AirConditionerReceiver receiver) {this.receiver = receiver;}@Overridepublic void exec() {this.receiver.cold();}
}// 制热命令,内部调用空调的制热操作
public class HotCommand implements Command {private AirConditionerReceiver receiver;public HotCommand(AirConditionerReceiver receiver) {this.receiver = receiver;}@Overridepublic void exec() {this.receiver.hot();}
}// 唱歌命令,内部调用小爱同学的唱歌
public class SingCommand implements Command {private XiaoAiTongXueReceiver xiaoAiTongXue;public SingCommand(XiaoAiTongXueReceiver xiaoAiTongXue) {this.xiaoAiTongXue = xiaoAiTongXue;}@Overridepublic void exec() {this.xiaoAiTongXue.sing();}
}// 讲笑话命令,内部调用小爱同学的讲笑话
public class JokeCommand implements Command {private XiaoAiTongXueReceiver xiaoAiTongXue;public JokeCommand(XiaoAiTongXueReceiver xiaoAiTongXue) {this.xiaoAiTongXue = xiaoAiTongXue;}@Overridepublic void exec() {this.xiaoAiTongXue.joke();}
}
- 定义Invoker
维护一组要执行的Command,其中Command的设置由客户端完成:
public class MyInvoker {// 自己用(仅本类用)private// 不可改变引用值 finalprivate final List<Command> commands = new ArrayList<Command>();// 设置一组命令,由命令来完成具体的动作,内部操作是如何完成的对用户是透明的public void addCommand(Command command) {this.commands.add(command);}// 执行命令public void execCommand() {commands.forEach(v -> v.exec());}
}
- 客户端
public static void main(String[] args) {// 创建具体命令的执行者们AirConditionerReceiver airConditionerReceiver= new AirConditionerReceiver();XiaoAiTongXueReceiver xiaoAiTongXueReceiver = new XiaoAiTongXueReceiver();// 创建命令Command singCommand = new SingCommand(xiaoAiTongXueReceiver);Command jokeCommand = new JokeCommand(xiaoAiTongXueReceiver);Command coldCommand = new ColdCommand(airConditionerReceiver);Command hotCommand = new HotCommand(airConditionerReceiver);// 把命令添加到invokerMyInvoker myInvoker = new MyInvoker();myInvoker.addCommand(singCommand);myInvoker.addCommand(jokeCommand);myInvoker.addCommand(hotCommand);myInvoker.addCommand(coldCommand);// 执行命令myInvoker.execCommand();
}
运行:
小爱同学唱歌了
小爱同学讲笑话了
空调制热了
空调制冷了
写在后面
参考文章列表
秒懂设计模式之命令模式(Command Pattern) 。