首页 > 解决方案 > 是否有任何常见的策略可以根据另一个对象的类型来选择要创建的对象类型

问题描述

想象一下,我有一个对象,它可以是许多不同类型中的任何一种,它们都派生自一个基类型。我想创建与第一个对象相关的第二个对象,因为它的类型取决于第一个对象的类型。然而,第二个对象的类型总是派生自第二个基类。

我的解决方案是让第一个对象通过虚拟方法创建第二个对象。

然而,在这种特殊情况下,我们根本不希望这两个类耦合。任何一个对象都不应该存在另一个对象。

这意味着必须有某种第三方中介对象基于第一个对象类型创建第二个对象。

因此,我选择的下一个解决方案是让这个中介器成为一个工厂,专门查看第一个对象的类型并基于它实例化第二个对象。

对我来说,这可行,但似乎不是一个理想的解决方案。如果工厂正在创建第一个对象,那么每当添加新的派生类型时,必须更新两个工厂并建立新的连接。

是否有任何常见的设计模式可以帮助解决这个问题并使代码更清晰?

编辑:正如@MustehssunIqbal 所述。这个问题是并行层次结构的经典案例。通过创建桥接或类似方法解决此问题的问题是这两个类需要保持解耦。

提供了一个具体的例子:

假设我有一个基处理器类,它被许多处理器子类继承。这对于当前的应用程序来说很好。然而,一个新的应用程序也想使用这些类,这是一个 GUI 应用程序。此应用程序希望为每个处理器创建一个 GUI 元素,并且每个单独类型的处理器还必须具有特定的 GUI 类型。

现在要停止在第一个应用程序中需要 GUI,处理器和 GUI 类必须解耦。

标签: oopdesign-patternsarchitecturesoftware-designfactory-pattern

解决方案


感谢您提供详细信息。这似乎是并行层次结构的情况。您有许多 UI 元素,例如按钮、列表 - 但在绘制这些元素时,您有三个按钮用于三个处理器,三个 TextAreas 用于三个处理器,等等。

每种处理器的 UI 层中的并行层次结构

正如评论中提到的,我建议实施桥接模式,其中可以抽象不同处理器的特定事物。ProcessorRenderer(下图)是UI层可以使用的抽象的东西。

UI 元素 (Glyph) 和 ProcessorRenderer 之间的桥梁

另一种类似的方法是使用应用程序外观层。正如您在编辑中提到的,您需要将处理器层次结构与 UI 层分开。我也同意这一点。我不希望 UI 层了解有关处理器的任何信息(或来自域层的任何信息)。UI 层应该是愚蠢的,它应该只绘制按钮、列表、单选按钮等。所以我建议引入一个应用程序外观层,它可以从域层了解处理器层次结构,并且会知道不同类型的UI 层的 UI 元素,但不应该知道“如何绘制 UI 元素”-> 那部分应该只有愚蠢的 UI 层知道。无论域如何,UI 层都是可测试的,而域对 UI 一无所知。Application Facade 层包含的是将 Domain 层对象转换为 UI 层可以使用的数据结构。您可以在此处阅读有关应用程序外观的更多信息:https://www.martinfowler.com/apsupp/appfacades.pdf

桥接模式:https ://en.wikipedia.org/wiki/Bridge_pattern

我在这里将 Application Facade 视为 Bridge 模式的一个特例,除了 Application Facade (ProcessorRenderer) 依赖于 UI 层,而在 Bridge 模式中,依赖关系是相反的。但那只是我的个人意见。

由于您在编辑中提到您希望将 UI 层与处理器层次结构完全分离,因此我在这里驳回了使用访问者模式的想法。还因为如果在层次结构中所做的一切都是渲染,那么只有一个 impl 的访问者,即 RenderingVisitor。这完全没问题,但我认为让它成为访客有点过头了。但是,如果您在各种类型的处理器上进行许多此类不同的操作,并且每种类型的处理器的每个操作都不同,那么我建议您改用访问者模式。:)

访问者模式:https ://en.wikipedia.org/wiki/Visitor_pattern#:~:text=In%20object%2Dorienting%20programming%20and,structures%20without%20modifying%20the%20structures 。


推荐阅读