使用分部类实现“模块化”是否很常见?


24

我最近在我们的代码库中遇到了一个情况,一个不同的团队创建了一个“神类”,其中包含约800个方法,并作为部分类分为135个文件。

我问了另一个团队。尽管我的直觉是从轨道上取笑,但他们坚持认为这是一种好的设计,是一种惯例,并且它促进了“模块化”和“易于实现”,因为新开发人员可以在几乎不了解其余知识的情况下使用功能系统的。

这实际上是常见的做法还是任何一个好主意?我倾向于立即采取措施降低这头野兽的生命(或至少阻止它进一步成长),但我愿意相信自己是错的。


6
用火杀死它!但是认真地说,其他团队是否可以为这种所谓的惯例提供任何引用?
MattDavey 2012年

1
没有。我确定他们正在冒烟,但是在我放下锤子之前,我正在尽我的努力。
约书亚·史密斯

他们为什么不一直这样做呢?
JeffO

3
请他们用一句话描述135个文件中的800种方法彼此之间的共同点。对于任何理智合理的班级,都应该可以回答这个问题。
Carson63000

3
@ Carson63000“它执行项目的所有必需功能。” 有你的一句话。
Ryathal

Answers:


39

这绝不是一个好主意。

存在局部类以帮助表单设计者。出于任何其他原因使用它们(可以说是出于其预期的目的,但这是另一回事)是一个坏主意,因为它导致难以理解的understand肿类。

这样看:如果在一个文件中拥有800个方法的God类是一件坏事,而我想每个人都会同意的话,那么一个拥有800个方法的God类又如何呢?分布在135个文件中,您知道哪里可能是件好事?


1
我大都同意,但我认为在某些情况下,partial即使没有生成的代码也很有用。也许当您有类似嵌套类的东西时?
svick

1
@svick:局部类很有趣,但通常不需要。我不确定为什么在嵌套类的情况下将一个类拆分为单独的文件会很有用。除非您希望嵌套类位于其自己的物理文件中。在那种情况下... maaaaybe没关系。;)
FrustratedWithFormsDesigner 2012年

5
有时,我将部分类用于显式接口实现-尤其是类似System.IConvertible之类的东西。某种程度上,似乎比在班上放置一个巨大的#region更为干净。
MattDavey 2012年

1
嵌套的类评论实际上是一个非常好的主意,我什至从未想到过。尽管...与组织无关,而不是“模块化”
Sheldon Warkentin,2012年

1
“存在局部类以帮助表单设计者。” 一般而言是正确的,但是我会添加“ ...和其他代码生成器。”。我同意您的其余回答;)
Silas 2015年

14

所以问题是:

这实际上是常见的做法还是任何一个好主意?

在目前可用的答案中,有一个响亮的否定。因此,我几乎没有其他事情可以解决,例如;甚至程序代码也可以模块化,包括除厨房水槽之外的所有内容,这并不是实现模块化的方式。一个巨人阶级分裂成的部分确实做到了,所有这些加在一起变成了一个大混乱。

但是,这个问题对于真正的关键部分是一个红色的鲱鱼。OP对此情况也有以下说法:

(...)虽然我的直觉是要从轨道上炸开核弹,但他们坚持认为...

(...)我倾向于立即采取措施降低这头野兽的生命(或至少阻止它进一步成长),但我愿意相信自己是错的。

稍安毋躁!

这是使我的具有象征意义的单片眼镜掉进具象形的茶中的东西。

我曾经遇到过类似的情况,请允许我告诉您:不要因为这样做的冲动而陷入困境。当然,您可以将Nuke Hammer of Justice放到团队中,但在这样做之前,请使自己面对以下难题:

如果你告诉球队他们的代码吸并会发生什么滚蛋

(...或类似的方式,但进攻性较小,这并不重要,因为如果决定对他们全力以赴,无论您做什么,他们都会被冒犯)

代码库的当前情况是什么?工作正常吗?然后,向他们的客户解释他们的代码本质上很烂时,您将遇到大麻烦。不管他们有什么理由:只要能正常工作,大多数客户都不在乎代码的组织方式。

也把自己放在鞋子里,他们会怎么做?让我为您带来以下可能的结果:

团队成员1: “所以这个家伙告诉我们,过去几年来我们做错了。”

2号和3号团队成员: “真是个混蛋。”

有影响力的团队成员4: “不必担心,我会去向管理层报告这是一种骚扰。”

看看那里有什么有影响力的4号团队成员?他去了管理层,减少了你在公司的业力。他可能是美籍意大利人,告诉每个人不要担心,但后来我会成为种族主义者。

让冒犯的团队陷入困境,让他们承认自己做错了这么长时间,这也是一个坏主意,并且会导致同样的事情。您将失去尊重和一些办公室政治业障。

即使您成功吸引了很多人对此进行签名,但为了“教团队一个教训”,也要记住,您是对相当聪明的人执行此操作的,这些人显然已经完成了一些工作。一旦代码将被重写/重构/处理/以任何方式处理,就会出现问题,就像您是firestarter一样您将承担责任

在这种情况下进行对抗主要是一场输赢游戏,因为它有可能成为怪怪游戏的恶性循环。对于这种情况,这是次优的结果。即使您获胜,您也会突然移交给其他人造成的混乱。

还有其他(非常成熟的)方式

曾经有过类似的情况,但是后来我在膝盖上拉了一支箭。因此,经过一段突然改变事业的箭头之后,我想到了Terrence Ryan的“ 驾驶技术变革”一书。它列出了几种怀疑论者的模式,这种人没有按照好主意行事。它们最有可能适用于OP的情况:

  • 不知情的人-他们确实不知道还有其他方法,或者根本不了解。初级开发人员通常适合此类别,但不一定。(说实话:我遇到了比这更聪明的初级开发人员。)
  • 牧群-与使用局部类相比,他们知道更好的技术,但不知道它们是否被允许。
  • 愤世嫉俗的人-他们只是为了争辩而争论说拥有部分阶级比你的想法更好。在人群中这样做很容易,而不是站在人群面前。
  • The Burned-由于某些奇怪的原因,他们不喜欢创建新的类,很可能他们认为这太难了。
  • 时间紧缩-他们太忙了,以至于不愿意修改代码。
  • 老板-他们认为:“行得通;为什么要打扰?”
  • 非理性-好吧,他们完全疯了。

这本书附有一系列策略等,但是在OP的情况下,这只是说服力。仅仅依靠反模式的事实来解决问题是不够的。

如果您出于提高代码质量的考虑,请至少让有问题的团队有机会重申并纠正自己的混乱情况。我个人会试着通过倾听和询问主要问题来影响他们,让他们讲述他们的故事:

  • 他们的神课到底在做什么?
  • 他们有什么问题吗?他们有错误吗?建议进行合理的修复,而不要告诉他们这样做。
  • 如果您是API的此类用户:是否有比使用整个代码更简单的方法来使用代码?提出更简单的示例,看看它们如何反应。
  • 您是否可以在不编写某些功能的情况下切换其他功能?
  • 他们需要一些培训吗?您能否说服管理层让他们去做,还是让他们开会讨论模式和做法?

... 等等。给他们一些小建议,使他们可以继续前进。这需要时间,并且需要一些办公室政治级的肘部润滑脂,但是耐心和勤奋是美德吗?


这是一个非常有见地的答案。如果您是新开发人员,则需要了解这一点。大多数经验丰富的开发人员在几年后就意识到了这一点,有些则从来没有做过。
FishySwede

6

MSDN的“ 部分类和方法”页面建议了两种使用部分类的情况:
1.将巨型类拆分为多个单独的文件。
2.放置自动生成的源代码。

Visual Studio大量使用了2(例如,用于aspx文件和winforms)。这是局部类的合理使用。

1是您的团队正在做的事情。我要说的是,当您拥有巨型类时,使用局部类是实现模块化的一种完全合理的方法,但是拥有巨型类本身是不合理的。换句话说,拥有一个巨大的类是一个坏主意,但是如果您要拥有一个巨大的类,那么部分类是一个好主意。

尽管如果您可以智能地将一个类拆分为不同的文件以供不同的用户使用,您是否可以将其拆分为单独的类呢?


+1表示“您不能将它分成几个单独的类吗?”。这正是我们的建议。似乎是常识,它原本应该这样做。
约书亚·史密斯

4

因此,最后,他们可以进行正常的程序开发,而无需任何OOP。它们具有一个包含所有方法,变量和诸如此类的全局名称空间。

要么说服他们他们做错了,要么让他们离开地狱。


1

实用程序类包含无法与其他方法合理组合以创建类的方法。如果您有800多种方法,分为135个文件,则似乎有人设法找到了一些常用方法...

仅仅因为您拥有一个实用程序类,并不意味着您不能拥有另一个实用程序类。

即使您有800个几乎不相关的方法,解决方案也不是一大类,而且文件很多。解决方案是一个名称空间,一些子名称空间和许多小类。这需要更多的工作(您必须为类以及方法命名)。但是,当需要清理这些混乱时,它将使您的生活变得更轻松,同时,它还将使智能感知的使用更加轻松(即,更容易发现使用方法的位置)。

不,这并不常见(文件数量多于自由功能数量)。


0

我一点都不喜欢。但是,也许分部类对开发人员有意义,因为它允许并发开发大量方法,尤其是在它们之间没有太多依赖的情况下。

另一种可能性是,那些局部类是为了修改自动生成的核心类而构建的。在这种情况下,请勿触摸它们,否则在重新生成时,定制代码将被剔除。

我不确定没有任何学习,任何人都可以轻松保持这种状态。现在,如果您杀死它,方法的数量将不会减少。对我来说,方法的数量和复杂性是真正的问题。如果这些方法确实属于该类,那么拥有1个巨大的文件并不会使您的生活变得更轻松,尤其是在维护方面,实际上,将所有这些代码暴露给诸如通配符搜索之类的愚蠢错误可能更容易出错。并更换。

因此要当心并证明杀死决定的合理性。另外,请考虑需要进行哪些测试。


0

从实用的设计角度出发,假设135个文件实际上将方法分组在一起,这与传统类将执行的操作类似,则完全可以。每个文件平均只有6种方法。它绝对不是设计项目的最流行或传统方式。试图改变它只会带来很多问题,而弊病不会带来真正的好处。使项目符合OO标准将解决许多问题。如果多个文件实际上没有提供任何有意义的分隔,则完全不同。


3
将程序代码重构到OO中通常会遇到这个问题-我认为解决此问题将是一项艰巨的任务,并教导团队正确地编写甚至更大的代码,最重要的是,约书亚将对明年(以及以后)发生的一切情况负责),如果他确实说服他们进行重构。这就是为什么没有人会太努力地进行这样的重构的原因(至少在看到结果后才如此)。同样,如果您认为这是一个很好的设计,那么,请在5年后重温此答案,然后让我们知道您的想法(似乎我每隔5年左右就会重新学习一次我对设计的了解)。
Bill K

@BillK如果您等待十年,您所知道的将可能是当前的“融入”设计理念。
Ryathal

135个文件通常进行分组相关的方法,但是(对我而言)仍然不是一个好主意。我想对该系统进行测试,但是对800种方法的hydra进行测试/模拟将是一个丑陋的难题。
约书亚·史密斯

@Ryathal并不是“内在”的东西,而是您认为是好的设计(出于充分的理由),然后,当您进行练习和改进时,就会意识到这并不像您想象的那样好。似乎每隔5年左右就会发生一次,一旦我意识到它使我对某些人的评论的反应变得缓和,因为我意识到他们实际上是优秀的设计师,他们(以及我们所有人)正在不断改进我们的实践。我唯一担心的程序员是谁不认为他们可以改进5年前编写的代码。
Bill K

0

除了已经指出的答案之外,局部类在分层设计中非常有用,在分层设计中,您需要组织功能,以将您的类层次结构交叉切割为单独的特定于层的文件。这样一来,您就可以使用解决方案资源管理器(按文件组织)浏览每个层的功能,并使用类视图浏览每个类的功能。我更喜欢使用支持mixin和/或特性的语言,但是如果很少使用局部类,则它是合理的选择,并且不应该替代良好的类层次结构设计。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.