命令模式的丑陋体验:OOP中的任何一点
本文关键字:OOP 任何一 体验 模式 命令 | 更新日期: 2023-09-27 18:17:49
我已经在我的系统中实现了一个命令模式,主要是因为我有几个层,我需要远程"调用"逻辑。
class DoWorkCommandMessage { int param; }
class DoWorkCommandHandler : Handler<DoWorkCommandMessage>
{
Execute(MyObject object) {
object.DoWork(message.param);
}
}
class MyObject
{
void DoWork(int param) {
_proxy.SendMessage(new DoWorkBinaryMessage(param));
}
}
正如你所看到的,我基本上是获得一个消息,将其转换为一个方法调用,然后将其转换回发送到另一个层的消息。
我觉得这里有点不对劲。
我最终重构了MyObject,删除了所有的方法,并用一个简单的ProcessMessage方法代替它们,该方法接受一个消息,翻译它,然后分派它。
这是OK的,除了MyObject最终主要是转换代码,而不是一个"对象"…
为了进行单元测试,我必须不断调用ProcessMessage(),而不是直接调用方法。
我正在寻找关于"短信"转换"vs"消息->方法->消息的方法。显然,消息和方法是密切相关的。
我认为混乱和/或困难在于您实际上并没有使用命令模式。你把它和短信混在一起了。你甚至可以在命令的名称中看到这一点……DoWorkCommandMessage
。在经典的Command模式中,这项工作实际上是由Command对象完成的。在消息传递方法中,消息作为DTO传递,并由处理程序执行。
AbstractCommand
+ Execute()
+ CanUndo()
+ Undo()
+ CanChain(cmd)
+ Chain(cmd)
该类的一个具体实例是:
MoveUnitCommand // a unit is a graphic piece on a game board
+ UnitId
+ Destination
+ Execute()
{
units = Units.Find(UnitId)
prevCoords = units.Position
units.Position = Destination
}
+ CanUndo() { return true; }
+ Undo()
{
units = Units.Find(UnitId)
units.Position = prevCoords
}
+ etc, etc
注意,命令子类不只是描述要做什么,它实际上根据您的系统状态起作用。