对立色彩空间
Martin Fowler在他的精彩的重构书中写道:“如果在多个地方看到相同的代码结构,那么,如果可以找到一种统一它们的方法,就可以确保程序会更好。” 然后,他描述了熟练的程序员如何使用提取和替换的双解剖刀切除重复的表达和转移的算法。
一连串的好建议几乎使人迷失了“结构”一词。 福勒似乎以一种不太正统的方式使用它。 Fowler所指的结构是一组元素及其之间的关系,当然表达了结构:构成元素的源代码行,顺序控制流,关系。 确实,在这种情况下(代码行)的多重性代表了最基本的复制形式,所有其他复制都建立在该复制形式上。 还有其他结构,更传统的结构,也反映了(也许是不完美的)基础文本基础。
更高层次的结构将方法建模为元素,将依赖项建模为关系。 在这种情况下,复制看起来像什么? 图1显示了缠满恶性疾病的程序的Spoiklin图 。
在图1中, a()
调用了其他五个方法, e()
, f()
, g()
, h()
和i()
。 b()
。 c()
。 这种结构形式不能保留方法调用的顺序,因此图1只能暗示而不是重复-抽象在源代码上浮起时抽象就流失了它们的信息-但是,正如我们稍后将看到的,实用主义轻易地消除了这种情况。理论约束。
考虑到图1成功地标识了一个结构重复,即a()
, b()
和c()
都完全容纳相同的方法调用序列。 该怎么办,结构解决方案应如何显示? 当然,该解决方案将三个序列一起粉碎为一个新方法d()
,然后调用原始的前三个方法,见图2。
在这里,我们可以看到,即使不是相反的情况,至少也要消除它的代价: 深度 。 图1的传递依存关系长两个元素。 在图2中,它们都拉伸了三个元素。 因此,这种根除的风险有增加连锁React的风险,但是重复(软件设计中所有邪恶的根源)似乎值得付出代价。
这可能很简单。 有什么比这种减少重复更为明显的呢? 在这一点上,大多数软件界人士都很少同意。 Fowler将代码重复提升到他的书中最重要的代码味道。 肯特·贝克(Kent Beck)在他的《极限编程说明》中写道:“当系统要求您重复代码时,它便要求重构。” JB Rainsberger声称只有简单设计的两个要求 ,其中之一是“最小化重复”。
问题在于,复制最小化首先需要复制标识,而在这一任务上,就像性能优化一样,机器出色,而人类却没有。 几种现代设计过程都敦促程序员首先满足功能要求,并暂时推迟功能闪烁设计所必需的结构调整。 在这种推迟的重构过程中,这些程序员自然会将精力集中在新增加的逻辑上,因此当本地添加内容反映远程未研究的软件包中的现有代码时,可能不会注意到。
手动根除重复的这种努力徒劳无功,即使是最流行的程序发布后很久也很伤心。 对最近审阅的FitNesse的一个随意处理显示,它散布着许多相同或几乎相同的代码片段,大多数很小,但是却引人注目,例如触手可及的PageDriver.requestPageSaveWithContentsByUserAndPassword()和ResponseRequester.execute()
如图所示。 3。
放大到更高的水平,图4展示了整个FitNesse程序的程序包图,其中黑色表示庆祝那些没有代码重复的程序包,而托管有重复代码的程序包则以红色表示,与所包含的重复次数成比例。
图4仅提供了方法级结构复制的摘要; 谁知道逐行代码分析器可能显示什么? 确实,问题已变得如此普遍,以至于某些程序员放弃了所有手动识别代码重复的尝试,而只依靠其不失败的源代码分析器来揭示问题。
当无脑的机械化彻底彻底消亡时,重复仍然需要如此令人恐惧的尊重,这并不奇怪吗?
摘要
上面的FitNesse的作者罗伯特·C·马丁(Robert C. Martin)出色,也许最雄辩地说 :“重复的代码是软件设计中万恶之源。 当一个系统中散布着许多相同或几乎相同代码的代码片段时,表明系统草率,粗心和纯粹的专业性。 所有软件开发人员应负有责无旁贷的责任,即在他们发现时消除并消除重复。”
发送无人机。
翻译自: https://www.javacodegeeks.com/2014/03/whats-the-opposite-of-duplication.html
对立色彩空间