9

在我的应用程序中,我有一个Controller由 main 方法启动的。控制器初始化钩子、数据库连接、UI、另一个连接和其他东西。它拥有程序的大部分状态(不,它不是单例)。在另一个示例中,机器人的控制器处理解释和发送命令。两者都是相当大的文件。

我已经阅读了有关上帝对象的内容,但我真的不知道如何将其拆分。如果我在 bot 中拆分解释器和调度器,它将产生一个可怕的调用链(类似于getBot().getParser().getOutput().sendMessage(recipient, message))。同样,在第一个控制器中,如果我将它们分开,您将只有包含字段和一些别名实用程序方法的 Data 对象。把它们分开只会让事情变得更糟。在你认为它不可维护之前,它实际上不是。我什至没有编写 Bot 控制器,但我仍然知道发生了什么。

但问题是 Bot 类有 2000 行长(如果我去掉 Javadoc 注释,可能会更短),而 Bot 大约有 1000 行长。很多行=上帝的对象。但是一个项目的一两个核心类可以吗?

4

4 回答 4

11

“很多行”并不意味着该类根本就是一个上帝对象,这是一个非常糟糕的基准,用于确定是否应该重构某些东西。有些事情非常复杂,需要一个复杂且固有的大对象。上帝对象的想法是类所做的。

例如,如果我制作了一个可以

DoMyTaxes()
GiveMeHugs()
LogThisError()
StartGameLoop()

该对象将有资格成为上帝对象,即使它可能只有 100 行代码。基本思想是,以上所有内容都是完全不相关的(在业务逻辑范围的末端),那么为什么它们都将成为同一个对象的一部分。如果我决定让拥抱持续更长时间,我最终可能会搞砸我的税收。输入国税局。

但是,如果您正在使用物理模拟器,可以说,并且Classical()该类将具有方法/对象,例如:

Space()
Time()
Velocity()
Speed()
Mass()
Acceleration()
Gravity()
Force()
Impulse()
Torque()
Momentum()
AngularMomentum()
Inertia()
MomentOfInertia()
ReferenceFrame()
Energy()
KineticEnergy()
PotentialEnergy()
MechanicalWork()
VirtualWork()
DAlembertsPrinciple()

(由维基百科提供)

这个物体不会是上帝的物体。这是一个复杂的对象。与牛顿物理学有关的一切都经过它,但它不是上帝的物体……它只是一个非常非常大的物体。上面的代码最终可能是数千行代码。

这个Quantum()对象会更加复杂,不用说。

重申一下,这个想法是关于程序的行为,而不是数据流

您不关心单个对象是否包含大量应用程序的数据,或者大多数流是否必须通过单个对象。对可维护性影响更大的是单个 God Class(tm) 包含太多行为(业务代码)。

如果你认为有问题,你可以尝试实现不同形式的中介,或者更丑陋的模式,比如依赖注入

于 2010-10-25T02:53:37.987 回答
3

如果您对类的大小和复杂性感到不舒服,那么它通常是一个很好的指标,表明可以完成更好的设计。但不要只衡量大小。如果一个类易于理解和遵循,但包含大量代码,这并不一定意味着它是重构的候选对象。我已经看到人们对此感到厌烦,他们在追求使事情变得更小的过程中造成的混乱比原始代码要糟糕得多。另一方面,我已经将课程从头到尾通读了好几遍,但仍然不知道它们在做什么。

我要问的问题是 - 如果我把它交给另一个开发人员,他们是否能够轻松理解和维护它?

如果答案是肯定的,那么很有可能你不需要做任何事情。如果不是,则需要进行重构。

参考上帝对象,阅读您的帖子,听起来这门课做得太多了。我想知道首先您是否可以将状态重新分解为一组模型对象作为起点。然后你的类开始看起来更像某种配置工厂。

于 2010-10-25T02:33:25.290 回答
2

我建议物理/运动引擎绝对应该与语言解释器分开;尽管语言解释器需要访问物理引擎的一些公共方法和属性,但机器人的两个方面没有理由应该在同一个类中。语言解释器本身可以细分为几个类,运动引擎也应如此。可能有主控对象,但代码量应该比较少。它,主要的运动引擎和主要的语言引擎,都应该将它们的大部分工作委托给组成它们的对象。

于 2010-10-26T01:46:13.760 回答
0

我认为这里的关键原则是“凝聚力”。

DoMyTaxes()
GiveMeHugs()
LogThisError()
StartGameLoop()

..没有凝聚力。

就像是 :

GiveMeHug()
GiveMeKisses()
GiveMeHugs(int noOfTimes)
GiveMeHugs(int noOfTimes, Person person)
GiveMeHugsAndKisses()

..具有凝聚力,因为所有方法都非常相似。你可以在一个类中有 1000 个内聚的方法,但它仍然不是一个上帝对象,因为类的责任仍然是有限的。

于 2013-02-15T09:57:07.660 回答