让我们假设我们在this way
中实现了命令模式我对Invoker在这里的作用感到有些困惑。从我的角度来看:
或者我错过了什么?
答案 0 :(得分:2)
如果我们确实需要历史记录(或在命令执行之前的任何类型的动作),那么在创建这个类时就有意义。但是它打破了单一责任原则,是吗?现在,它不仅是代表,还在那里存储历史。
我完全赞同安德烈亚斯的回答。如果您认为自己正在执行多项职责,请将其分解为不同的方法。
单一责任原则很好听,但我们不应过分关注这一原则。如果你严格遵循这个原则,我确信代码库中包含太多小类。我不认为软件行业的任何大项目都使用这一原则。我们可以做的最好的事情是在同一个类中针对不同的动作有不同的方法。
如果我们不需要历史记录,我就不会看到创建此调用程序的目标,只需执行委派即可。唯一的原因是它只是一个假设,我们将来在命令执行之前/之后需要某种逻辑吗?
Command 模式的核心USP是 Invoker 。它将客户端(发件人)和接收器分离。
来自oodesign文章:
客户端要求执行命令。 Invoker接受命令,封装它并将其放入队列中,以防首先要做其他事情,以及负责所请求命令的ConcreteCommand,将其结果发送给Receiver。
我在下面的SE问题中解释了 Invoker 的作用:
Command Pattern seems needlessly complex (what am I failing to understand?)
答案 1 :(得分:1)
您是否阅读过您引用的维基百科文章?
使用调用者对象可以方便地执行有关命令执行的簿记,以及为调用者管理的命令实现不同的模式,而不需要客户端知道簿记或模式的存在
责任/目的不是授权,而是簿记,因此不会违反单一责任原则。
你可以争辩说,如果Invoker同时执行簿记和模式管理,它有两个职责,但如果需要,你可以将调用者内部的分开。
请记住,Command模式并不关心单一责任。这是一个不同的模式,如果你需要的话,它可以由你自己应用。
答案 2 :(得分:1)
在此特定设计模式中,Invoker
可选择执行有关命令执行的记录。
因此,我不会过分担心是否有必要保留历史,也不会过分违反单一责任原则(如果“簿记”变得复杂,调用者总是可以将簿记委托给另一个班级。)
那么为什么Invoker
存在呢?
它基本上为您提供了一个注册Command
操作的单点,这些操作尽可能少地了解实际问题域 - 只关注如何在execute()
上调用Command
。
这样做的好处包括易于理解的设计模式和减少的耦合(Invoker
不需要了解Light
)。
答案 3 :(得分:0)
来自http://www.oodesign.com/command-pattern.html:
在餐厅用餐的例子非常好 试图更好地解释模式是如何工作的:服务员(祈求者) 接受客户在他垫上的订单。然后订单排队 订单做饭,然后到厨师(接收者)那里 处理。