类别:行为型设计模式
目的:解耦行为的接收方和行为的实际处理逻辑
完整代码参考:https://1drv.ms/u/s!AquRvPzqx59Ri3MMlUz2cbydE0Eu?e=X6DGEG
典型场景
gui窗口界面上的一个按钮对象,点击后执行一断逻辑处理代码
硬编码
构造一个按钮类,并在点击(click)时执行业务逻辑代码,参考代码如下:
public class Button {
private String label;
public void click() {
// doBusinessLogic(); 逻辑处理代码
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
}
核心问题
按钮和按钮点后的业务逻辑代码耦合在一起
- button的复用变得困难
- 逻辑代码的复用变得困难
解决方式:命令模式,将业务逻辑代码和按钮分开,使得button和逻辑代码都变得比较容易复用
模式实现
将逻辑代码单独进行封装,这部分封装就是命令模式中的命令
单独封装业务逻辑
public interface Command {
void execute();
}
public class BusinessLogicCommand implements Command {
@Override
public void execute() {
System.out.println("business logic here...");
}
}
按钮中持有对业务逻辑的引用
public class Button {
private String label;
private Command command;
public Button(Command command) {
this.command = command;
}
public void click() {
command.execute();
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
}
使用方式
var command = new BusinessLogicCommand();
var button = new Button(command);
button.click();
可以看到命令使用了接口、可以方便的进行业务逻辑的扩展
一些注意的点
命令模式中的Command对象特性
- 可被持久化、比如从关键状态中恢复以前的状态
- 可被撤销、比如执行删除命令时,先保存被删除的内容,可在需要时恢复被删除的内容
java 持久化参考代码如下(stat为需要持久化的对象)
// 持久化对象到文件
var fileStream = new FileOutputStream("stat.txt");
var objectStream = new ObjectOutputStream(fileStream);
objectStream.writeObject(stat);
objectStream.close();
// 从文件恢复对象
var fileStream = new FileInputStream("history.txt");
var objectStream = new ObjectInputStream(fileStream);
var stat = (Stat) objectStream.readObject();
为什么命令模式更好
- 避免大量的耦合
- 减少基础组件的重复、比如界面上许多的按钮,大部分可以重用