【问题标题】:Role of Invoker class in Command pattern命令模式中调用者类的作用
【发布时间】:2016-09-27 11:27:18
【问题描述】:
假设我们在this way 中实现了命令模式
我对 Invoker 在这里的角色有点困惑。在我看来:
- 如果我们确实需要历史记录(或命令执行前的任何类型的操作),那么创建此类是有意义的。但是它违反了单一责任原则,是吗?现在它不仅是一个委托,它还在那里存储历史记录。
- 如果我们不需要历史,我看不到创建这个调用程序的目标,它只是执行委托。是个
唯一的原因只是一个假设,即我们将来在命令执行之前/之后需要某种逻辑?
还是我错过了什么?
【问题讨论】:
标签:
java
design-patterns
command-pattern
【解决方案1】:
如果我们确实需要历史记录(或命令执行之前的任何类型的操作),那么创建这个类是有意义的。但是它违反了单一责任原则,是吗?现在它不仅是一个委托,它还在那里存储历史记录。
我完全同意 Andreas 的回答。如果您认为您正在执行多个职责,请将它们分解为不同的方法。
单一职责原则很好听,但我们不应过多关注该原则。如果您严格遵循该原则,我确信代码库中包含太多的小类。我不认为软件行业的任何大型项目都使用这个原则。我们能做的最好的事情是在同一个类中为不同的操作提供不同的方法。
如果我们不需要历史,我看不到创建这个调用程序的目标,它只是执行委托。唯一的原因是否只是一个假设,即我们将来在命令执行之前/之后需要某种逻辑?
Command模式的核心USP是Invoker。它将客户端(Sender)和Receiver解耦。
来自oodesign文章:
客户端要求执行一个命令。 Invoker 接收命令,将其封装并放入队列中,以防先有其他事情要做,而负责请求命令的 ConcreteCommand 将其结果发送给 Receiver。
我已经在下面的 SE 问题中解释了 Invoker 的作用:
Command Pattern seems needlessly complex (what am I failing to understand?)
【解决方案2】:
您是否阅读了您引用的维基百科文章?
使用调用程序对象可以方便地执行有关命令执行的簿记,以及实现由调用程序对象管理的命令的不同模式,而无需客户端知道存在簿记或模式.
责任/目的不是委托,而是记账,因此没有违反单一责任原则。
您可以争辩说,如果 Invoker 同时进行簿记和模式管理,它有两个职责,但如果需要,您可以将其 在调用者内部分开。 p>
请记住,命令模式不关心单一职责。那是一种不同的模式,如果你需要的话,你可以同时应用这两种模式。
【解决方案3】:
在这个特定的设计模式中,Invoker 可以选择对命令执行进行记录。
所以我不会太担心是否需要保留历史记录,也不会太担心这是否违反单一责任原则(如果“簿记”变得复杂,调用者总是可以将簿记委托给另一个类)。
那么为什么Invoker 存在呢?
它基本上为您注册Command 操作提供了一个点,该操作对实际问题域知之甚少——只知道如何在Command 上调用execute()。
这样做的好处包括易于理解的设计模式和减少耦合(Invoker 不需要了解有关Light 的任何信息)。