管理多个类的类是“上帝对象”吗?

时间:2010-12-30 05:24:03

标签: oop language-agnostic god-object

阅读the wikipedia entry about God Objects,它说当一个类知道太多或太多时,它就是一个神对象。

我看到了这背后的逻辑,但如果这是真的,那么你如何结合每一个不同的阶级?您是否总是使用主类来连接窗口管理,数据库连接等?

4 个答案:

答案 0 :(得分:15)

主要功能/方法可以知道窗口,数据库和其他对象的存在。它可以执行诸如将模型引入控制器之类的重要任务。

但这并不意味着它管理所有细节。它可能对数据库或窗口的实现方式一无所知。

如果确实如此,可以指责它是上帝的对象。

答案 1 :(得分:7)

god对象是一个对象,它直接或间接地包含对应用程序中大多数(如果不是全部)对象的引用。正如问题所述,在应用程序中避免使用神对象几乎是不可能的。 某些对象必须保存对各种子系统的引用:UI,数据库,通信,业务逻辑等。请注意,上帝对象不需要是应用程序定义的。许多框架都内置了神对象,其名称如“应用程序上下文”,“应用程序环境”,“会话”,“激活器”等。

问题不在于是否存在神对象,而在于它是如何被使用的。我将以一个极端的例子说明......

假设在我的应用程序中,我想标准化显示数字时显示的精确小数位数。但是,我希望精度可以配置。我创建了一个类,其职责是将数字转换为字符串:

class NumberFormatter {
    ...
    String format(double value) {
        int decimalPlaces = getConfiguredPrecision();
        return formatDouble(value, decimalPlaces);
    }

    int getConfiguredPrecision() {
        return /* what ??? */;
    }
}

问题是,getConfiguredPrecision如何找出返回的内容?一种方法是为NumberFormatter提供对它存储在名为_appContext的成员字段中的全局应用程序上下文的引用。然后我们可以写:

return _appContext.getPreferenceManager().getNumericPreferences().getDecimalPlaces();

通过这样做,我们刚刚将NumberFormatter变成了一个神对象!为什么?因为现在我们可以(间接地)通过其_appContext字段引用应用程序中的任何对象。这不好吗?是的,是的。

我要为NumberFormatter编写单元测试。让我们设置参数......它需要一个应用程序上下文?! WTF,我需要模拟57种方法。哦,它只需要pref经理...... WTF,我必须模拟14种方法!数字首选!?!拧它,这个类很简单,我不需要测试它......

假设应用程序上下文有另一种方法getDatabaseManager()。上周我们使用的是SQL,因此该方法返回了一个SQL数据库对象。但本周,我们决定更改为NoSQL数据库,该方法现在返回一个新类型。 NumberFormatter是否受到此更改的影响?嗯,我记不清了...是的,它可能是,我看到它在构造函数中需要一个应用程序上下文...让我打开源代码并看看......不,我们很幸运:它只访问getPreferenceManager() ...现在让我们检查将应用程序上下文作为参数的其他93个类......

如果对首选项管理器或数字首选项对象进行了更改,则会出现同样的情况。这个故事的寓意是,一个对象应该仅仅包含对执行其工作所需的事物的引用,并且只包含那些事物。在NumberFormatter的情况下,它需要知道的是一个整数 - 小数位数。它可以由知道幻数的应用程序上帝对象(或者pref管理器或更好的数字prefs)直接创建,而无需将格式化程序转换为上帝对象本身。此外,任何需要格式化数字的组件都可以被赋予格式化程序而不是上帝对象。四处游动。

因此,总而言之,问题不在于上帝对象的存在,而在于无情地赋予其他物体上帝般地位的行为。

顺便说一句,正面解决这个问题的设计原则被称为Law of Demeter。或者“在餐馆付款时,给服务器你的钱而不是你的钱包。”

答案 2 :(得分:3)

根据我的经验,这通常发生在您处理的代码是“随时随地开发”项目管理(或缺乏项目管理)的产品时。当项目未经过思考和计划,对象责任松散且未正确委派时。在这些场景中,您会发现“上帝对象”是代码中没有任何明显组织或委派的代码。

不同类别的相互联系或耦合不是神对象的问题,事实上,神对象多次可以完成大部分(如果不是全部)它的衍生儿童的责任,并且是相当不可预测的(由开发人员以外的任何人决定他们的责任是什么。

答案 3 :(得分:2)

简单地了解“多重”课程并不能使一个人成为上帝;了解多个类以解决应该分成几个子问题的问题 确实让一个人成为上帝。

我认为重点应该放在一个问题应该分成几个子问题,关于给定对象知道的类的数量(正如你所指出的,有时候知道几个课是必要的。)

上帝过度炒作。