在我的应用中,我有一个Controller
,它是由main方法启动的。控制器初始化钩子,数据库连接,UI,另一个连接和其他东西。它占据了程序的大部分状态(不,它不是Singleton)。在另一个例子中,有一个用于机器人的控制器,用于处理解释和发出命令。两者都是非常大的文件。
我已经阅读了上帝的物品,但我真的不知道如何将它分开。如果我将机器人中的解释器和调度员分开,它将会产生一个可怕的调用链(类似于getBot().getParser().getOutput().sendMessage(recipient, message)
)。类似地,在第一个控制器中,如果我分开,你将只有包含字段的数据对象和一些别名实用程序方法。将它们拆分会让事情变得更糟。在你认为它不可维护之前,实际上并非如此。我甚至没有写Bot控制器,但我仍然知道发生了什么。
问题是Bot类是2000行(如果我拿出Javadoc注释可能会更短)并且Bot大约是1000行。很多行=上帝的对象。但是对于项目的一个或两个核心类是否可以?
答案 0 :(得分:11)
“很多行”并不意味着该类是一个神对象,这是一个可怕的可怕基准,用于确定你是否应该重构一些东西。有些事情非常复杂,需要一个复杂且固有的大对象。上帝对象的想法是所做的。
例如,如果我创建了一个可以
的对象DoMyTaxes()
GiveMeHugs()
LogThisError()
StartGameLoop()
该对象可以作为一个神对象,即使它可能只有100行代码。基本思想是以上所有内容完全不相关(在业务逻辑的频谱末端),所以为什么它们都将成为同一个对象的一部分。如果我决定让拥抱持续更长时间,我最终可能会搞砸我的税。输入IRS。
但是,如果您正在使用物理模拟器,那么,Classical()
类将具有方法/对象,例如:
Space()
Time()
Velocity()
Speed()
Mass()
Acceleration()
Gravity()
Force()
Impulse()
Torque()
Momentum()
AngularMomentum()
Inertia()
MomentOfInertia()
ReferenceFrame()
Energy()
KineticEnergy()
PotentialEnergy()
MechanicalWork()
VirtualWork()
DAlembertsPrinciple()
(由维基百科提供)
此对象不是神对象。这是一个复杂的对象。所有涉及牛顿物理学的东西都经历过它,但它不是上帝的对象......它只是一个非常大的对象。上述内容最终可能会成千上万行代码。
Quantum()
对象将更加复杂,不用说。
重申一下,这个想法是关于程序的行为,而不是数据流:
你不关心单个物体 拥有很多应用程序的数据,或者 大多数流量是否必须通过 单个对象。有什么影响 关于维持性是单身上帝的时候 Class(tm)拥有太多行为 (商业代码)。
如果您认为存在问题,可以尝试实施不同形式的mediation或更为丑陋的模式,例如dependency injection。
答案 1 :(得分:3)
如果您对课程的大小和复杂性感到不舒服,那么通常可以很好地指出可以进行更好的设计。但是不要仅仅衡量尺寸。如果一个类很容易理解和遵循,但包含很多代码,那并不一定意味着它是重新分解的候选者。我看到人们对此感到厌烦,他们为追求小事而创造的混乱局面比原始代码更糟糕。另一方面,我已经多次阅读过端到端的课程,但仍然不知道他们做了什么。
我要问的问题是 - 如果我把它交给另一位开发人员,他们是否能够轻松理解和维护它?
如果答案是肯定的,则可能性是您不需要做任何事情。如果没有,则重新分解是有序的。
参考上帝的对象,阅读你的帖子,听起来好像这堂课做得太多了。我想知道你是否可以将状态重新分解为一组模型对象作为起点。然后你的课程看起来更像某种配置工厂。
答案 2 :(得分:2)
我建议物理/运动引擎绝对应该与语言解释器分开;虽然语言解释器需要访问物理引擎的一些公共方法和属性,但机器人的两个方面应该在同一个类中是没有理由的。语言解释器本身可以细分为几个类,运动引擎也应如此。可能存在主控制对象,但它应该具有相对少量的代码。它,主要的运动引擎和主要语言引擎都应该将他们的大部分工作委托给构成它们的对象。
答案 3 :(得分:0)
我认为这里的关键原则是“凝聚力”。
DoMyTaxes()
GiveMeHugs()
LogThisError()
StartGameLoop()
..没有凝聚力。
类似的东西:
GiveMeHug()
GiveMeKisses()
GiveMeHugs(int noOfTimes)
GiveMeHugs(int noOfTimes, Person person)
GiveMeHugsAndKisses()
..具有凝聚力,因为所有方法都非常相似。你可以在一个类中拥有1000个内聚方法,它仍然不是一个上帝对象,因为这个类的责任仍然是有限的。