我正在写一个绘画程序。我的基本课程是:
class Workspace { Bitmap b; List<Command> undoList; }
class Command { void execute(); }
class ClearScreen extends Command
class BlurEffect extends Command
class View { Bitmap screen; }
class Interface
工作空间对象包含表示程序状态的位图。 Command类表示用于在工作空间上执行命令的Command模式,其中撤消通过重置工作空间的状态和重放旧命令来工作。界面对象链接按钮从用户按下到命令,视图将工作空间状态呈现到屏幕位图。
我的问题是代表命令。 ClearScreen命令很简单;它只是告诉工作区用白色填充位图,它会立即发生。 BlurEffect命令更复杂;模糊采用模糊屏幕多少的参数,执行可能花费一些时间并且用户通常想要在选择一个之前尝试一些模糊参数(即,他们需要预览在提交之前模糊效果将是什么样的)。如何修改以上内容以支持这种预览?
我能想到的最好的方法是使用以下内容扩展Command:
class BlurCommand extends Command
{
void setBlurAmount(float x) ...
// View can use this to render a preview to the
// screen bitmap, where the workspace bitmap isn't modified in the process
void preview(Workspace w, Bitmap b)
void execute() // apply blur effect to workspace
}
所以想法是,在界面中,单击“模糊”按钮创建一个新的BlurCommand对象,View中的“渲染屏幕”方法将开始调用“预览”方法来渲染屏幕并“执行”仅在用户想要应用效果时调用。
这是我能做到的最干净的方式吗?我试图坚持模型 - 视图 - 控制器设计,不希望我的预览行为使事情变得复杂。
答案 0 :(得分:0)
是的,您也可以应用模糊,如果取消操作则撤消模糊,如果参数更改,则撤消并重做模糊。如果重放整个命令堆栈太耗时,可以在应用模糊之前拍摄快照。
答案 1 :(得分:0)
您是否有任何单元测试可以测试您的绘图程序的当前功能?我认为有一件事可以帮助您实现可靠的设计是使用TDD(测试驱动开发/设计)。编写一个模拟“预览”类型操作的测试,然后进行测试。一旦您的现有测试和新预览测试都通过,那么请查看您的应用程序代码。
答案 2 :(得分:0)
到目前为止,您的设计看起来很棒。以下是我的观点:使用模糊命令所面临的问题是更多此类事情的指示,因此应在设计中添加更多此类命令。因此,您可以为Command创建两个子类 - FastCommand
和SlowCommand
。 FastCommand只有doIt
和undoIt
方法,只需执行并将其添加到命令堆栈即可。 SlowCommand应该是一个异步命令,它有一个两步操作过程 - 预览&amp;承诺。第一次执行SlowCommand时,它应该被执行但不会被添加到命令堆栈中。相反,只需将其作为参考保留在工作区中。当用户实际确认操作时,再次执行它(这次是真实的),然后将其移动到命令堆栈。
可能不需要View类。
使用SlowCommand的实际undo-redo机制,您可以根据性能和可用内存决定最佳方法 - 创建缓冲区副本然后丢弃它,或者在同一缓冲区上运行逆算法。如果您发现在应用程序中同时使用这两种策略,则可以在命令中使用Strategy Pattern。