对于设计模式类,教师要求我的团队开发一个支持绘制和持久化字形的应用程序,非常类似于GoF的WYSIWYG编辑器。
我的团队决定使用分层架构,层次递减:演示,控制器,逻辑,持久性。
Logic维护一组字形表示,它们各自的位置以及一些形状独特的属性。教师建议我们使用Builder模式创建统一的持久性机制,因为CSV和XML是必需的持久性格式。
当我们尝试在持久层中设计Builder时,会出现问题。因为我们正在使用图层,所以不允许Persistence图层明确地了解Glyph类型,更不用说将它们从抽象形式转换为各自的形状。这让我感到头疼,甚至将每个Builder作为构造函数传递给我。
下一个问题是很难概括Builder所采用的类型。矩形具有线不具有的属性。
我在抓住如何做到这一点上遇到了很多麻烦。我理解Builder模式,但有些事情并不是点击。我是否滥用了这种模式,还是我不能正确地解决这个问题呢?
编辑:教师没有说我们必须重新加载持久格式。我的结束解决方案显然应该很容易,但对于我目前的问题,我只专注于保存
答案 0 :(得分:2)
不确定是否需要使用Builder。 工厂/注册管理机构和可串行化可能更重要。
使持久层不知道显式字形类型的方式,同时仍然赋予它保存和加载特定字形实例的能力,是通过某种反射机制。无论是内置于语言中的东西(如.Net中的Reflection,还是Delphi / C ++ Builder中的RTTI),或者您自己手工制作的东西。
要自己手工制作解决方案,您需要让所有字形类型都来自常见的“可序列化”基类型,或者让它们都实现“序列化”接口。持久层只需要知道这个基本类型或接口 - 无论你选择哪个。
使用接口意味着字形并不都需要公共基类型,使用公共基类型意味着您可以在该基类型中实现常见行为并避免重复。
“可序列化”基类型或接口应该为持久层提供通过唯一(字符串)ID识别字形类型的方法,迭代要保持/加载的属性的方法;和多边形实例化字形的方法(Delphi中的虚拟构造函数和元类说话)。
获取字形类型ID并迭代要保留的属性应该足以保存实例。
迭代属性应该简单明了,但如果你想“设计模式化”,你可以考虑使用访问者。当组合和聚合字形(绘图应用程序中的分组)进入图片时,这可能会使生活变得更加简单,没有双关语:-)。关于这一点,你也可以考虑看一下复合模式,尽管这可能对你被要求做的事情有点过分。
要从持久性存储加载字形,您需要一个注册表,其中字形类型与唯一名称(字符串)链接,因此持久层可以查找类型以从持久化信息中的字符串实例化。每个字形类型都需要在注册表中注册,以便可以通过持久层找到并实例化它。查看工厂方法和抽象工厂模式以获取更多相关信息。