坏人记事本_谁怕大坏人呢?

坏人记事本

超大型类是在软件世界中费力的,令人费解的黑洞,是由于失控的积极反馈所致:类的增长如此之大,以至于程序员担心进行重构的任何尝试,而只是将更多的功能转储到其中,从而使它更有可能在可怕的重构和抛弃更多功能之前,下一位程序员也会面目全非。 所有人都盯着催眠吸积盘,知道必须销毁此类,其功能分散到许多较小的类别,但没人知道从哪里开始。 哪些方法应该先移? 应该如何做出选择? 哪些标准可以帮助做出决定?



即使是受人尊敬的人也承认动摇。 福勒在其出色的《 重构》一书中写道:

“如果我不确定是否要移动一种方法,那么我将继续研究其他方法。 转移其他方法通常会使决策更容易。 有时仍然很难做出决定。 实际上,那没什么大不了的。 如果很难做出决定,那么可能没什么大不了的。 然后我根据本能选择; 毕竟,我以后总是可以再次更改它。”

当急切需要协助的几个客观工程标准时,这种本能的Swift求助似乎令人遗憾。

以图1为例,它显示了( alas )Spoiklin Soice本身的SequenceDiagram类的spoiklin图 ,其中每个圆圈代表一种方法,每条线依赖。

图1:类SequenceDiagram。

图1:类SequenceDiagram。

此类已陷入困境,这是一种不愉快的状态,需要创建一个新类,一些SequenceDiagram的功能可能会移入该类。 程序员应该从哪里开始寻找移动方法? 四个条件有帮助。

首先,重构旨在在捐助者阶层和新阶层之间取得某种平衡。 将大多数方法从捐助者类转移到新类中似乎没有什么意义,因为这只是将复杂性从一类转移到另一类,什么也没解决。

第二,新阶级应该本身具有完整性。 它不会将随机选择和未连接的方法移到新类中:它的方法必须满足某些共同的目的。 共享依赖性提供了对共享责任的强烈指示,新类的方法应形成一个相互依赖的单元,这是通过从捐助者类中选择一组已经协作的方法来最好地实现的目标。 因此,程序员寻求的不是临时移动方法,而是移动相关方法的集合。

第三,任何候选方法集的迁移都应该对系统的其余部分造成最小的破坏。 现代工具和IDE极大地简化了移动方法的机制,但是只有程序员才能保护所遗留的设计免受不当的毁坏。 正如新的阶级必须享有正直,捐助者的树桩也必须一样。 取决于候选集中任何方法的方法的数量提供了由重构引起的破坏程度的指示。 这个数字应在候选人资格方面有很强的发言权。

有了这三个条件(很快就会遇到第四个条件),程序员可以系统地,客观地进行搜索。 这些标准不能保证解决方案,但至少可以避免过早辞职。 在下面的图表(Spoiklin Soice的“可封装的”分析)中,将研究受影响的集合,其中,受影响的集合是任何特定方法的所有传递依赖关系所涉及的方法集。 每个方法的圆圈将根据对该方法的影响集的依赖关系数量显示为红色:深红色圆圈表示该方法的子项(以及孙子项等)上有许多依赖项,这表明该方法不适合重定位。 另一方面,淡红色的圆圈表示其后代几乎没有依赖项的方法,因此建议进行运输的优秀候选人。 工具提示将提供这些依赖方法的实际数量。 (黑圈表示存在少于两个依赖项的方法。)

在下面的图2中,程序员单击了execute()方法以突出显示其受影响的集合(再次:其传递依赖的方法),发现只有五个其他方法依赖于整个集合的元素。

图2:探测可移动方法:太多。

图2:探测可移动方法:太多。

但是,由于第一个条件,该选择失败了:将如此大量的方法移至新类中可能会使新类几乎与捐助者一样大而复杂。 程序员并没有气ter ,单击下面的图3中的drawDiagram()方法可以进行进一步的探查

图3:探索可移动方法:仍然太多。

图3:探索可移动方法:仍然太多。

不幸的是,这里再次受到影响的drawDiagram()方法集显得太大而无法平衡两个类之间的行为,因此它也必须被拒绝。 然后, drawClassLines()方法进入十字线,请参见图4。

图4:探索可移动方法:影响太大。

图4:探索可移动方法:影响太大。

在这里,移动的方法组看起来很理想,该组既不会太大也不会太小。 该选择仅受工具提示中的数字打扰:其他十二种方法取决于该组的各种方法,使其提取过于混乱(该方法的深红色本来是警告)。 搜索继续。 在下面的图5中,程序员单击drawLineFromCallingToCalled()方法。

图5:探索可移动方法:合适的候选对象。

图5:探索可移动方法:合适的候选对象。

成功。 此选择提供了一组六个方法,它们全部服务于同一主服务器,而其他六个方法仅依靠该方法。 这在集合大小和中断之间取得了良好的平衡,并为首次重构提供了良好的候选者。 下面的图6显示了重构的过程,六个方法中的每个都依次从SequenceDiagram类中抽出。

图6:移动六种方法。

图6:移动六种方法。

重构之后,出现SequenceDiagram类,如图7所示。

图7:第一个重构结果。

图7:第一个重构结果。

注意,在顶部增加了一些额外的方法:这些是使新类从保持数据所有权的SequenceDiagram中读取一些数据所必需的getter方法; 这些方法最终将陷入陷入泥潭的接口中,以避免循环依赖。 它们只是吸气剂,它们几乎没有增加捐助者阶层的复杂性,因此是值得的妥协。 出于兴趣的考虑,图8显示了新类CallingLine及其引以为傲的新租户。

图8:一个新类诞生了:CallingLine。

图8:一个新类诞生了:CallingLine。

当然,该任务尚未完成。 尽管操作成功,但供体类别仍然过重,必须移植其他方法。 在这里,第四个也是最后一个标准起作用: depth 。 好的设计要求在可行的情况下最小化传递依赖项长度。 研究图7揭示了两个新方法集,它们将自己暴露为明显的候选对象:它们从图的底部“伸出”,是最深的可达方法。 图9显示了第一个positionOwningSetNameBoxes()方法的受影响集合。

图9:继续探测,第一个新候选者。

图9:继续探测,第一个新候选者。

图10显示了第二个,即stripeBackground()方法。

图10:继续探测,第二个新候选者。

图10:继续探测,第二个新候选者。

尽管这两个受影响的设备都不具有很大的优势,但是它们每个都只有四个传入的依赖项,因此它们的重定位只会造成较小的破坏。 图11显示了两个受影响的集从SequenceDiagram的迁移。 请注意,随着过程的进行, SequenceDiagram的结构享受的深度减少。

图11:再移动七个方法。

图11:再移动七个方法。

第二次重构产生一个SequenceDiagram类,如图12所示。

图12:第二次重构后的SequenceDiagram。

图12:第二次重构后的SequenceDiagram。

最后,研究图12的更深层次结构还可以发现另一个候选对象: processOwningSetNamesPrinting()方法的受影响集合,请参见下面的图13。

图13:最终探测和候选。

图13:最终探测和候选。

尽管数量很少,但是这套方法将依赖关系扩展到新创建的类上,从而激发其与供者一样属于新类。 图14显示了这三种方法的提取。

图14:移动最后三种方法。

图14:移动最后三种方法。

图15显示了最终结果,即重构后的SequenceDiagram类,该类是孤立的,易于理解,依赖项也更易于跟踪。

图15:类SequenceDiagram,重新加载。

图15:类SequenceDiagram,重新加载。

将此类与原始的预先重构的类进行比较,请参见图16。

图16:原始的SequenceDiagram。

图16:原始的SequenceDiagram。

图17显示了新的CallingLine类的最终形式,它的结构也不复杂。

图17:最终的CallingLine类。

图17:最终的CallingLine类。

摘要

恐惧是缺乏经验。

一些程序员讨厌重构大型类的任务,因为他们根本不知道从哪里开始。

其他人知道的更好。 他们知道,无论类有多大,迭代应用的一组简单条件都可以帮助阐明整个过程(此外,这套套件也适用于过分的软件包)。 这些重构者学会了完成这些任务,找出了位于大多数系统内部的巨大怪兽,跌入事件视界,疯狂地嘲笑挠痒的意大利面。

翻译自: https://www.javacodegeeks.com/2014/05/whos-afraid-of-the-big-bad-class.html

坏人记事本

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值