Builder 模式使用不当?

发布于 2024-09-24 08:28:25 字数 518 浏览 2 评论 0原文

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

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

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

当我们尝试在持久层中设计构建器时,问题就出现了。因为我们使用的是图层,所以持久层不允许明确地了解字形类型,更不用说将它们从抽象形式转换为单独的形状了。这让我摸不着头脑,不知道如何将每个构建器作为其构造函数传递。

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

我很难掌握如何做到这一点。我了解构建器模式,但有些东西就是不点击。我是否滥用了该模式,或者我没有正确地将其适应问题?

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

For a design patterns class, the instructor asked my team to develop an application that supports drawing and persisting glyphs, very similar to the WYSIWYG editor from GoF.

My team decided to use a Layered architecture, with descending layers: Presentation, Controller, Logic, Persistence.

The Logic maintains a collection of glyph representations, their respective positions, and some shape-unique properties. The instructor suggested we use the Builder pattern to create uniform persistence mechanism, as CSV and XML are required persistence formats.

The problem comes about when we attempt to design the Builder within the Persistence layer. Because we're using Layers, the Persistence layer is not permitted to know about Glyph types explicitly, let alone cast them from their abstract form to their individual shapes. This has me scratching my head as for what to even pass each Builder as its constructor.

The next problem is that its hard to generalize the types that the Builder takes. Rectangles have properties that Lines don't.

I'm having a lot of trouble grasping how to do this. I understand the Builder pattern, but something just isn't clicking. Am I misusing the pattern, or am I not fitting it to the problem correctly?

Edit: The instructor didn't say we have to load the persisted formats back in. My ending solution should obviously make this easy, but for my current problem, I'm only focused on saving.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

回眸一笑 2024-10-01 08:28:25

不确定您是否需要为此构建器。 工厂/注册表和可序列化可能更切题。

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

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

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

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

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

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

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

Not sure you need a Builder for this. Factories / Registries and serializability are probably more to the point.

The way you make the persistence layer ignorant of explicit glyph types, while still giving it the ability to save and load specific glyph instances, is through some sort of reflection mechanism. Either something built into the language (like Reflection in .Net, or RTTI in Delphi / C++ Builder), or something you handcraft yourself.

To handcraft a solution yourself you will need to have all glyph types descend from a common "serializable" base type or have them all implement a "serialize" interface. The persistence layer only needs to know about this base type or interface - whichever you choose.

Using an interface means the glyphs do not all need a common base type, using a common base type means you can implement common behaviour in that base type and avoid some duplication.

The "serializable" base type or interface should provide the persistence layer with the means to identify the glyph type by a unique (string) ID, the means to iterate over properties to be persisted / loaded; and the means to instantiate a glyph polymorfically (virtual constructors and meta classes in Delphi speak).

Getting the glyph type id and iterating over the properties to be persisted should be enough for saving instances.

Iterating over properties should be simple and straightforward, but if you want to "design patternize" this you could consider using a Visitor. Which might make life a lot simpler when composed and aggregate glyph's (Grouping in drawing applications) get into the picture, no pun intended :-). With regard to that, you could also consider having a look at the Composite pattern, though that may be overkill for what you have been asked to do.

To load glyphs from a persistent store, you will need a registry somewhere where glyph types are linked with a unique name (string) so the persistence layer can look up the type to instantiate from a string in the persisted information. Each glyph type will need to register itself in the registry so it can be found and instantiated by the persistence layer. Look up Factory Method and Abstract Factory pattern for more information on this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文