【问题标题】:OO-design for painting program interface面向绘制程序界面的OO设计
【发布时间】:2011-03-16 22:36:35
【问题描述】:

我正在编写一个绘画程序。我的基本课程是:

  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 类表示用于在工作空间上执行命令的命令模式,通过重置工作空间的状态和重放旧命令来撤消工作。界面对象将用户按下的按钮链接到命令,视图将工作区状态呈现到屏幕位图。

我的问题是表示命令。 ClearScreen 命令很简单;它只是告诉工作区用白色填充位图,它会立即发生。 BlurEffect 命令更复杂; blurring 需要一个参数来确定屏幕模糊程度,执行可能需要一些时间,并且用户通常希望在选择一个模糊参数之前尝试一些模糊参数(即他们需要在提交之前预览模糊效果的样子)。如何修改上述内容以支持这种预览?

我能想到的最好的办法是用类似的东西扩展 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 
  }

所以思路是,在界面中,点击“blur”按钮会创建一个新的BlurCommand对象,View中的“render the screen”方法会开始调用“preview”方法来渲染屏幕并“execute”仅在用户想要应用效果时调用。

这是我能做到的最干净的方法吗?我正在尝试坚持模型-视图-控制器设计,并且不希望我的预览行为使事情复杂化。

【问题讨论】:

    标签: java user-interface design-patterns architecture interface


    【解决方案1】:

    是的,或者您可以应用模糊,如果操作被取消则撤消它,或者如果参数更改则撤消并重做它。如果重放整个命令堆栈太耗时,可以在应用模糊之前拍摄快照。

    【讨论】:

    • 谢谢,我也考虑过这个。模糊图像比从磁盘加载快照更快。在这种情况下,最好使用 View 的位图来预览图像,而不是在 Workspace 的位图上预览结果,这将迫使我从快照中恢复以尝试另一种模糊。
    【解决方案2】:

    您是否有任何单元测试来测试您的绘图程序的当前功能?我认为真正能帮助您实现可靠设计的一件事是使用 TDD(测试驱动开发/设计)。编写一个模拟“预览”类型操作的测试,然后使该测试通过。一旦您的现有测试和新的预览测试全部通过,然后看看您的应用程序代码是什么样的。

    【讨论】:

    • 我现在只是在设计。当然,单元测试是个好主意。
    • 关于 TDD 的一点是,您不是先设计代码,而是先编写测试,然后让代码的设计从测试期望系统工作的方式演变。
    • 我不确定这对这里有什么帮助。有许多实现可以通过,例如模糊预览和模糊应用测试。我正在寻找一个干净的实现,而不仅仅是一个能够通过测试的实现。
    • 我不确定您是否了解 TDD 的工作原理。从理论上讲,坐下来预先设计一个“干净”的实现可能很好,但是如果当您尝试实现该设计时,由于极端情况而失败,那么所有这些设计工作都将是徒劳的。当您首先编写测试时,最好的设计就会自然而然地出现。我建议阅读 TDD 循环:编写测试,使其通过,重构。
    • 我了解 TDD,我只是不明白预先做一些设计以计划更大的问题,这些问题肯定会在以后咬你,而且有点灵活。对我来说似乎很明智。例如,我过去已经编写了一个原型,但没有考虑撤消/重做,而改造该功能是一场噩梦。当你可以避免的时候重构并不有趣。不得不重写我所有的命令类和单元测试是我不想做的事情。
    【解决方案3】:

    到目前为止,您的设计看起来很棒。这是我的观点:你在使用 blur 命令时遇到的问题预示着会有更多这样的事情发生,因此应该在你的设计中加入更多这样的命令。因此,您可以为 Command 创建两个子类 - FastCommandSlowCommand。 FastCommand 只有doItundoIt 方法,将简单地执行并将其添加到命令堆栈中。 SlowCommand 应该是一个异步命令,它有两步处理 - 预览和提交。第一次执行 SlowCommand 时,它应该被执行但不被添加到命令堆栈中。相反,只需将其保存在工作区中作为参考。当用户实际确认该操作时,再次执行它(这次它执行真实的操作),然后将其移至命令堆栈。

    View 类可能不是必需的。

    对于 SlowCommand 的实际撤消重做机制,您可以根据性能和可用内存来决定最佳方法 - 创建缓冲区副本然后将其丢弃,或者可能在同一缓冲区上运行逆算法。如果您发现自己在应用程序中同时使用了这两种策略,则可以在命令中使用Strategy Pattern

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-02
      相关资源
      最近更新 更多