我最近在公司的一位高级开发人员审核了我的代码。他批评我的设计使用了太多的课程。我很想听听你的反应。
我的任务是创建一个服务,该服务生成一个xml文件,因为它操作了3个其他xml文件。我们将这些 aaa.xml , bbb.xml 和 ccc.xml 命名为。该服务分两个阶段进行。在第一阶段,它会针对 bbb.xml 清除 aaa.xml 。在第二阶段,它将第一阶段的产品与 ccc.xml 合并,以产生最终结果。
我选择了一个包含三个类的设计:一个XmlService类,它使用了另外两个类,一个scrubber类和一个merger类。我保持擦洗和合并类是分开的,因为这两个类都很大并且具有不同的逻辑。
我认为我的方法很好,因为它让我的课程变得小而有凝聚力。我的方法也有助于控制我的测试类的大小。
高级开发人员声称,清理和合并类只能由XmlService类使用,因此应该是它的一部分。他觉得这会使XMLService具有凝聚力,这就是他所说的具有凝聚力的意思。他还认为以这种方式分手,会使他们松散凝聚力。
具有讽刺意味的是,我试图打破这些课程以达到凝聚力。你怎么看?谁对或错?我们都对吗?谢谢你的建议。答案 0 :(得分:13)
如果您按照single responsibility principle(根据问题的基调,我认为您确实遵循它),那么答案很明确:
这是非常广泛而且确实是主观的 - 因此与你的同事的斗争。在你这边,你可以争辩说:
此外,我认为你的老板对凝聚力有误解。将其视为焦点:程序的焦点越窄,凝聚力越高。如果卫星类中的代码在服务类中合并,则后者变得不那么集中(不那么有凝聚力)。人们普遍认为,较高的内聚力优于较低的内聚力。试着启发他/她对此的看法。
答案 1 :(得分:8)
Cohesion衡量代码体内功能的相关程度。也就是说,如果合并和擦洗没有很强的相关性,包括它们在同一个类中都会降低凝聚力。
Single Responsibility Principle在这里也值得一提。创建一个仅用于擦洗的类,另一个用于合并的目的遵循这个原则。
我说你的方法比两者更好。
答案 2 :(得分:2)
你会把这些课命名为什么? ScrubXml
和MergeXml
是很好的名字。 ProcessXML
和ScrubAndMergeXml
不是,第一个太笼统,第二个有连词。只要没有一个类完全依赖于一个或另一个的内部(即低耦合),那么你就有了很好的设计。
名称在确定凝聚力方面非常有用。一个有凝聚力的模块做一件事,因此有一个简单的特定名称。一个不止一件事的模块缺乏凝聚力,需要更通用或更复杂的名称。
如果X仅使用Y,则将X中的功能合并到Y中的一个问题是还原广告:如果您的调用图是非循环的,那么您将在一个类中完成所有功能。
答案 3 :(得分:2)
作为一个从GodClass建筑节目中退回多年的人,现在正努力避免将来的错误;使用单个类制作6000到10000行单源单元的错误,超过250种方法,200个数据字段,以及超过100行的一些方法,单一责任原则看起来像是值得防范未开明的主管的偏好。
但是,如果您的主管和您在2000行代码属于一个类别还是三个类别的问题上存在分歧,那么我认为您比我更接近理智。也许这是规模和观点的问题。一些面向对象的编程爱好者喜欢每个类别的某个“独立系数”,直接违反了关于如何提高内聚力和最小化耦合的普遍理解的想法。
一组能够很好地协同工作的3个类,客观上是一个面向对象的系统,而不是单个类做同样的事情。有人可能会争辩说,如果你只使用一个类来编写应用程序,那么应用程序根本不是面向对象的。
答案 4 :(得分:1)
如果擦除器和合并在主类的上下文之外没有意义,那么我同意您的审阅者,特别是如果您必须公开任何实现细节以允许这种分离。如果您使用的语言支持嵌套的私有类或类似的东西,那么这可能是维护逻辑分离的合理替代方法,而不会将实现细节暴露给主类的外部使用者。
答案 5 :(得分:0)
这是一个非常主观的领域,根据编码和样式指南以及批准您的代码的人而有所不同。
那就是说,如果你的设计辩护没有成功,而你的高级团队成员仍然坚持要合并你的课程,那么你必须妥协:
你已经把逻辑分开了。编写一个服务类并保持方法与其他好的设计分开,然后编写一个粘合方法。在每个方法上方添加一些注释,说明如果将来需要,可以轻松地将它们分区为多个类。