2

对于设计模式课程,讲师要求我的团队开发一个支持绘制和持久字形的应用程序,非常类似于 GoF 的 WYSIWYG 编辑器。

我的团队决定使用分层架构,具有递减层:表示、控制器、逻辑、持久性。

Logic 维护一组字形表示、它们各自的位置和一些形状独特的属性。讲师建议我们使用 Builder 模式来创建统一的持久性机制,因为 CSV 和 XML 是必需的持久性格式。

当我们尝试在 Persistence 层中设计 Builder 时,问题就出现了。因为我们使用的是 Layers,所以 Persistence 层不允许明确了解 Glyph 类型,更不用说将它们从抽象形式转换为各自的形状。对于将每个 Builder 作为其构造函数传递的内容,这让我摸不着头脑。

下一个问题是很难概括 Builder 采用的类型。矩形具有线条没有的属性。

我很难掌握如何做到这一点。我了解 Builder 模式,但有些东西没有点击。我是在滥用模式,还是我没有正确地解决问题?

编辑:讲师没有说我们必须重新加载持久格式。我的最终解决方案显然应该让这很容易,但对于我目前的问题,我只专注于保存。

4

1 回答 1

2

不确定您是否需要 Builder。工厂/注册表和可序列化可能更重要。

使持久层忽略显式字形类型,同时仍使其能够保存和加载特定字形实例的方法是通过某种反射机制。要么是语言内置的东西(如 .Net 中的反射,或 Delphi / C++ Builder 中的 RTTI),要么是你自己手工制作的东西。

要自己手工制作解决方案,您需要让所有字形类型都源自一个通用的“可序列化”基本类型,或者让它们都实现一个“序列化”接口。持久层只需要知道这个基本类型或接口——无论你选择什么。

使用接口意味着字形并不都需要通用的基本类型,使用通用的基本类型意味着您可以在该基本类型中实现通用行为并避免一些重复。

“可序列化”基本类型或接口应为持久层提供通过唯一(字符串)ID 识别字形类型的方法,以及迭代要持久/加载的属性的方法;以及以多态方式实例化字形的方法(在 Delphi 中使用虚拟构造函数和元类)。

获取字形类型 id 并遍历要持久化的属性应该足以保存实例。

迭代属性应该简单明了,但如果你想“设计模式化”,你可以考虑使用Visitor。当组合和聚合字形(绘图应用程序中的分组)进入图片时,这可能会使生活变得更简单,没有双关语:-)。关于这一点,您还可以考虑查看Composite模式,尽管这对于您被要求做的事情来说可能是多余的。

要从持久存储加载字形,您将需要一个注册表,其中字形类型与唯一名称(字符串)链接,以便持久层可以查找类型以从持久信息中的字符串实例化。每个字形类型都需要在注册表中注册自己,以便持久层可以找到并实例化它。查找工厂方法抽象工厂模式以获取更多信息。

于 2010-09-22T06:34:17.147 回答