我是设计模式的新手,希望更好地了解何时实现命令模式。根据我的理解,命令模式旨在将请求和满足该请求所需的逻辑封装到其自己的对象中。
为更复杂的请求创建命令是有意义的,例如生成和保存某些数据库结果的 PDF 报告。例如:
public class PdfExport implements Command {
private MyEntityDao someDao = new MyEntityDaoImpl();
public PdfExport( ... ) {
// Set up command here...
}
@Override
public void execute() {
List<MyEntity> data = someDao.getData();
// Complex logic to create and export PDF...
}
}
但是假设我们只有一个非常简单的任务,例如通过名称字段删除单个记录。例如:
public class DeleteRecordByName implements Command {
private MyEntityDao someDao = new MyEntityDaoImpl();
String name;
public DeleteRecordByName(String name) {
this.name = name;
}
@Override
public void execute() {
someDao.deleteByName(name);
}
}
如您所见,第二个命令中实际上没有实现任何逻辑。我能想到这样做的唯一原因是,您拥有分层架构,并且希望将 DAO 排除在客户端代码之外,或者保留命令历史记录。
为像删除单个记录这样简单的事情创建命令有什么好处吗?
作为一个后续问题,在创建命令对象有意义之前是否需要涉及一定数量的逻辑?
是的,使用简单命令的原因有很多。 GoF 书从第 235 页开始列出了五个适用点。
在需要时使用命令模式
- 通过要执行的操作来参数化对象...命令是回调的面向对象替代品。
- 在不同时间指定、排队和执行请求。命令对象 可以拥有独立于原始请求的生命周期。
- 支持撤消。命令的执行操作可以存储状态,以便在命令本身中反转其效果。
- 支持日志记录更改,以便在系统出现问题时可以重新应用它们 崩溃。
- 围绕基于原语操作的高级操作构建系统。这种结构在支持交易的信息系统中很常见。
本书增加了更多细节;其中一些功能需要扩展命令接口,而不仅仅是
execute()
方法;但在回答OP时,请注意,这些功能都不涉及命令执行的任何特别复杂的逻辑。
Java 中命令的典型示例是 Runnable 和 Callable。考虑一下使用简单甚至微不足道的逻辑来实现这些的频率。