【问题标题】:Factory object causes stackoverflowexception due to dependancy upon itself工厂对象由于依赖自身而导致stackoverflow异常
【发布时间】:2011-06-24 16:15:10
【问题描述】:

我有一个 c# 工厂对象,它通过工厂方法创建对象,使用对象列表作为源。

对象列表是这样创建的:

public WidgetFactory()
    {
        widgetLibrary = new List<WidgetModel>();

        //Add all widgets
        widgetLibrary.Add(new ClientsWidget());
        widgetLibrary.Add(new InstallationsWidget());
        etc.

我的应用程序的各个部分以不同的方式访问此列表以获得所需的对象类型。

但我现在要求列表中的一个对象(即小部件)需要使用小部件工厂本身。显然这会导致循环引用。

我怎样才能改变我的设计来适应这种需要?

【问题讨论】:

    标签: c# factory-pattern circular-dependency


    【解决方案1】:

    但我现在要求列表中的一个对象(即小部件)需要使用小部件工厂本身。显然这会导致循环引用。

    我怎样才能改变我的设计来适应这种需要?

    通常,对象不应依赖为构造创建它们的工厂,因为它会导致这个问题。如果您可以推送对工厂的引用,但直到需要时才使用它,它可能会解决问题。

    如果您绝对需要这样做,那么最好的方法可能是在工厂中懒惰地实例化对象。您可以使用List&lt;Lazy&lt;WidgetModel&gt;&gt;,而不是让您的WidgetFactory 在内部包含List&lt;WidgetModel&gt;。这将允许单个“小部件”仅根据需要进行评估,这意味着当相关小部件尝试引用工厂时,它将被完全加载。

    【讨论】:

    • 第一个想法奏效了,我只是需要更加小心地在这种情况下使用工厂。
    【解决方案2】:

    但我现在有一个要求,列表中的一个对象(即一个小部件)需要使用小部件工厂本身。显然这会导致循环引用。

    我怎样才能改变我的设计来适应这种需要?

    你的模型是错误的。一旦汽车离开 NUMMI 工厂的装配线,它就不再依赖工厂来正常运行。

    另外,我质疑你们工厂的设计。你为什么要new 实例化构造函数。那服务的目的是什么?

    您可能应该告诉我们更多关于您的模型以及您认为需要此模型的原因。赔率是,正确完成,你没有。

    【讨论】:

    • 使用这个类比,被生产的对象是另一个汽车工厂。这个工厂正在为 UI 元素创建模型,但我现在需要创建一个映射到工厂的 UI 元素。这有意义吗?
    • @Jon Eastwood:听起来这家工厂做得太多了(建造工厂和 UI 小部件?)。你应该把职责分开。
    【解决方案3】:

    WidgetFactory 的构造函数不应该调用它正在构建的事物的构造函数。相反,WidgetFactory 应该有一个方法 (BuildWidgets) 来完成所有工作。

    然后其他对象可以使用工厂,而不会导致此级联活动重新开始。

    【讨论】:

    • 我同意这一点,我认为这是问题的根源,但我不知道如何改变它。我需要一种方法来枚举工厂可以创建的对象的可能类型,而不必为每个对象显式编写构建方法。
    【解决方案4】:

    首先,将 Widget 创建移出 WidgetFactory 的构造函数。这应该在初始化方法中或在 CreateWidget(Type) 方法中按需发生。

    要使工厂实例可用于 Widget 实例,您可以执行以下几种不同的操作之一:

    1. 让 WidgetFactory 在创建 Widget 时传递“this”
    2. 使用单例模式:添加静态属性WidgetFactory.Instance并初始化一次;让所有 WidgetFactory 用户访问该属性,而不是创建一个新实例。
    3. 使用dependency injection 模式——这里很难提供简短的描述。

    【讨论】:

    • 抱歉,你只是在抛出一些流行语,希望其中一个是对的吗?
    • @Jason 哈!不,但我明白你为什么这么说。这两种方法都是 OP 问题的有效解决方案,但我想我的答案可以使用更多细节。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-11
    • 2023-03-20
    • 2023-02-05
    • 1970-01-01
    • 1970-01-01
    • 2016-03-31
    • 2018-08-18
    相关资源
    最近更新 更多