通过重构得到更深层的理解

2024-08-26 00:52
文章标签 理解 重构 深层 得到

本文主要是介绍通过重构得到更深层的理解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

通过重构得到更深层的理解是一个涉及很多方面的过程。我们有必要暂停一下,把一些要点归纳到一起。有三件事情是必须要关注的:
(1) 以领域为本;
(2) 用一种不同的方式来看待事物;
(3) 始终坚持与领域专家对话。
在寻求理解领域的过程中,可以发现更广泛的重构机会。一提到传统意义上的重构,我们头脑中就会出现这样一幅场景:一两位开发人员坐在键盘前面,发现一些代码可以改进,然后立即动手修改代码(当然还要用单元测试来验证结果)。这个过程应该一直进行下去,但它并不是重构过程的全部。这里会在传统代码重构方法的基础上呈现了一幅全面的重构视图。

开始重构

获得深层理解的重构可能出现在很多方面。一开始有可能是为了解决代码中的问题——一段复杂或笨拙的代码。但开发人员并没有使用(代码重构所提供的)标准的代码转换,相反,他们认为问题的根源在于领域模型。或许是领域中缺少一个概念,或许是某个关系发生了错误。
与传统重构观点不同的是,即使在代码看上去很整洁的时候也可能需要重构,原因是模型的语言没有与领域专家保持一致,或者新需求不能被自然地添加到模型中。重构的原因也可能来自学习:当开发人员通过学习获得了更深刻的理解,从而发现了一个得到更清晰或更有用的模型的机会。
如何找到问题的病灶往往是最难和最不确定的部分。在这之后,开发人员就可以系统地找出新模型的元素。他们可以与同事和领域专家一起进行头脑风暴,也可以充分利用那些已经对知识做了系统性总结的分析模式或设计模式。

探索团队

不管问题的根源是什么,下一步都是要找到一种能够使模型表达变得更清楚和更自然的改进方案。这可能只需要做一些简单、明显的修改,只需几小时即可完成。在这种情况下,所做的修改类似于传统重构。但寻找新模型可能需要更多时间,而且需要更多人参与。
修改的发起者会挑选几位开发人员一起工作,这些开发人员应该擅长思考该类问题,了解领域,或者掌握深厚的建模技巧。如果涉及一些难以捉摸的问题,他们还要请一位领域专家加入。这个由4~5人组成的小组会到会议室或咖啡厅进行头脑风暴,时间为半小时至一个半小时。在这个过程中,他们画一些UML草图,并试着用对象来走查场景。他们必须保证主题专家(subject matter expert)能够理解模型并认为模型有用。当发现了一些令他们满意的新思路后,他们就回去编码,或者决定再多考虑几天,先回去做点别的事情。几天之后,这个小组再次碰头,重复上面的过程。这时,他们已经对前几天的想法有了更深入的理解,因此更加自信了,并且得出了一些结论。他们回到计算机前,开始对新设计进行编码。要想保证这个过程的效率,需要注意几个关键事项。
自主决定。可以随时组成一个小的团队来研究某个设计问题。这个团队只工作几天,然后就可以解散了。这种团队没有长期存在的必要,也不必有复杂的组织结构。
注意范围和休息。在几天内召开两三次短会就应该能够产生一个值得尝试的设计。工作拖得太长并没什么好处。如果讨论毫无进展,可能是一次讨论的内容太多了。选一个较小的设计方面,集中讨论它。
练习使用UBIQUITOUS LANGUAGE。让其他团队成员(特别是主题专家)参与头脑风暴会议是练习和精化UBIQUITOUS LANGUAGE的好机会。这样,原来的开发人员可以得到更完善的UBIQUITOUS LANGUAGE,并反映到编码中。
成熟的头脑风暴是灵活机动、不拘泥于形式的,而且具有令人难以置信的高效率。

借鉴先前的经验

我们没有必要总去做一些无谓的重复工作。用于查找缺失概念或改进模型的头脑风暴过程具有巨大的作用,通过这个过程可以收集来自各个方面的想法,并把这些想法与已有知识结合起来。随着知识消化的不断开展,就能找到当前问题的答案。
我们可以从书籍和领域自身的其他知识源获得思路。尽管相关领域的人员可能还没有创建出适合运行软件的模型,但他们可能已经把概念很好地组织到了一起,并发现了一些有用的抽象。把这些知识结合到知识消化过程中,可以更快速地得到更丰富的结果,而且这个结果也更为领域专家们所熟悉。
有时我们可以从分析模式中汲取他人的经验。这些经验对于帮助我们读懂领域起到了一定的作用,但分析模式是专门针对软件开发的,因此应该直接根据我们自己在领域中实现软件的经验来利用这些模式。分析模式可以提供精细的模型概念,并帮助我们避免很多错误。但它们并不是现成的"菜谱"。它们只是为知识消化过程提供了一些供给。随着零散知识的归纳,必须同时处理模型关注点和设计关注点。同样,这并不意味着总是需要从头开发一切。当设计模式既符合实现需求,又符合模型概念时,通常就可以在领域层中应用这些模式。
同样,当一种常见的形式体系(如算术逻辑或谓词逻辑)与领域的某个部分非常符合时,可以把这个部分提取出来,并根据它来修改形式系统的规则。这可以产生非常简练且易于理解的模型。

针对开发人员的设计

软件不仅仅是为用户提供的,也是为开发人员提供的。开发人员必须把他们编写的代码与系统的其他部分集成到一起。在迭代过程中,开发人员反复修改代码。开发人员应该通过重构得到更深层的理解,这样既能够实现柔性设计,也能够从这样一个设计中获益。
柔性设计能够清楚地表明它的意图。这样的设计使人们很容易看出代码的运行效果,因此也很容易预计修改代码的结果。柔性设计主要通过减少依赖性和副作用来减轻人们的思考负担。这样的设计是以深层次的领域模型为基础的,在模型中,只有那些对用户最重要的部分才具有较细的粒度。在这样的模型中,那些经常需要修改的地方能够保持很高的灵活性,而其他地方则相对比较简单。

重构的时机

如果一直等到完全证明了修改的合理性之后才去修改,那么可能要等待太长时间了。项目正在承受巨大的耗支,推迟修改将使修改变得更难执行,因为要修改的代码已经变得更加复杂,并更深地嵌入到其他代码中。
持续重构渐渐被认为是一种"最佳实践",但大部分项目团队仍然对它抱有很大的戒心。人们虽然看到了修改代码会有风险,还要花费开发时间,但却不容易看到维持一个拙劣设计也有风险,而且迁就这种设计也要付出代价。想要重构的开发人员往往被要求证明其重构的合理性。虽然这看似合理,但这使得一个本来就很难进行的工作变得几乎不可能完成,而且会限制重构的进行(或者人们只能暗地里进行)。软件开发并不是一个可以完全预料到后果的过程,人们无法准确地计算出某个修改会带来哪些好处,或者是不做某个修改会付出多大代价。
在探索领域的过程中、在培训开发人员的过程中,以及在开发人员与领域专家进行思想交流的过程中,必须始终坚持把"通过重构得到更深层理解"作为这些工作的一部分。因此,当发生以下情况时,就应该进行重构了:
设计没有表达出团队对领域的最新理解;
重要的概念被隐藏在设计中了(而且你已经发现了把它们呈现出来的方法);
发现了一个能令某个重要的设计部分变得更灵活的机会。
我们虽然应该有这样一种积极的态度,但并不意味着可以随随便便做任何修改。在发布的前一天,就不要进行重构了。不要引入一些只顾炫耀技术能力而没有解决领域核心问题的"柔性设计"。无论一个"更深层的模型"看起来有多好,如果你不能说服领域专家们去使用它,那么就不要引入它。万事都不是绝对的,但如果某个重构对我们有利,那么不妨在这个方向上大胆前进。

危机就是机遇

在达尔文创立进化论后的一个多世纪中,人们一直认为标准的进化模型就是物种随着时间缓慢地改变(在一定程度上这种改变是稳定的)。突然之间,这个模型在20世纪70年代被"间断平衡"(punctuated equilibrium)模型取代了。它对原有进化论进行了扩展,认为**长期的缓慢变化或稳定变化会被相对来说很短的、爆发性的快速变化所打断。然后事物会进入一个新的平衡。**软件开发与物种进化之间的不同点是前者具有明确的方向(虽然在某些项目上可能并不明显),尽管如此软件开发仍遵循这种进化规律。
传统意义上的重构听起来是一个非常稳定的过程。但通过重构得到更深层理解往往不是这样的。在对模型进行一段时间稳定的改进后,你可能突然有所顿悟,而这会改变模型中的一切。这些突破不会每天都发生,然而很大一部分深层模型和柔性设计都来自这些突破。
这样的情况往往看起来不像是机遇,而更像危机。例如,你突然发现模型中有一些明显的缺陷,在表达方面显示出一个很大的漏洞,或存在一些没有表达清楚的关键区域。或者有些描述是完全错误的。
这些都表明团队对模型的理解已经达到了一个新的水平。他们现在站在更高的层次上发现了原有模型的弱点。他们可以从这种角度构思一个更好的模型。
通过重构得到更深层理解是一个持续不断的过程。人们发现一些隐含的概念,并把它们明确地表示出来。有些设计部分变得更具有柔性,或许还采用了声明式的风格。开发工作一下子到了突破的边缘,然后开发人员跨越这条界线,得到了一个更深层的模型,接下来又重新开始了稳步的改进过程。

参考

《领域驱动设计 软件核心复杂性应对之道》 Eric Evans 著, 赵俐 盛海艳 刘霞 等译, 任发科 审校

这篇关于通过重构得到更深层的理解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1107088

相关文章

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

【C++高阶】C++类型转换全攻略:深入理解并高效应用

📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C++ “ 登神长阶 ” 🤡往期回顾🤡:C++ 智能指针 🌹🌹期待您的关注 🌹🌹 ❀C++的类型转换 📒1. C语言中的类型转换📚2. C++强制类型转换⛰️static_cast🌞reinterpret_cast⭐const_cast🍁dynamic_cast 📜3. C++强制类型转换的原因📝

深入理解RxJava:响应式编程的现代方式

在当今的软件开发世界中,异步编程和事件驱动的架构变得越来越重要。RxJava,作为响应式编程(Reactive Programming)的一个流行库,为Java和Android开发者提供了一种强大的方式来处理异步任务和事件流。本文将深入探讨RxJava的核心概念、优势以及如何在实际项目中应用它。 文章目录 💯 什么是RxJava?💯 响应式编程的优势💯 RxJava的核心概念

如何通俗理解注意力机制?

1、注意力机制(Attention Mechanism)是机器学习和深度学习中一种模拟人类注意力的方法,用于提高模型在处理大量信息时的效率和效果。通俗地理解,它就像是在一堆信息中找到最重要的部分,把注意力集中在这些关键点上,从而更好地完成任务。以下是几个简单的比喻来帮助理解注意力机制: 2、寻找重点:想象一下,你在阅读一篇文章的时候,有些段落特别重要,你会特别注意这些段落,反复阅读,而对其他部分

深入理解数据库的 4NF:多值依赖与消除数据异常

在数据库设计中, "范式" 是一个常常被提到的重要概念。许多初学者在学习数据库设计时,经常听到第一范式(1NF)、第二范式(2NF)、第三范式(3NF)以及 BCNF(Boyce-Codd范式)。这些范式都旨在通过消除数据冗余和异常来优化数据库结构。然而,当我们谈到 4NF(第四范式)时,事情变得更加复杂。本文将带你深入了解 多值依赖 和 4NF,帮助你在数据库设计中消除更高级别的异常。 什么是

分布式系统的个人理解小结

分布式系统:分的微小服务,以小而独立的业务为单位,形成子系统。 然后分布式系统中需要有统一的调用,形成大的聚合服务。 同时,微服务群,需要有交流(通讯,注册中心,同步,异步),有管理(监控,调度)。 对外服务,需要有控制的对外开发,安全网关。

Java IO 操作——个人理解

之前一直Java的IO操作一知半解。今天看到一个便文章觉得很有道理( 原文章),记录一下。 首先,理解Java的IO操作到底操作的什么内容,过程又是怎么样子。          数据来源的操作: 来源有文件,网络数据。使用File类和Sockets等。这里操作的是数据本身,1,0结构。    File file = new File("path");   字

理解java虚拟机内存收集

学习《深入理解Java虚拟机》时个人的理解笔记 1、为什么要去了解垃圾收集和内存回收技术? 当需要排查各种内存溢出、内存泄漏问题时,当垃圾收集成为系统达到更高并发量的瓶颈时,我们就必须对这些“自动化”的技术实施必要的监控和调节。 2、“哲学三问”内存收集 what?when?how? 那些内存需要回收?什么时候回收?如何回收? 这是一个整体的问题,确定了什么状态的内存可以

理解分类器(linear)为什么可以做语义方向的指导?(解纠缠)

Attribute Manipulation(属性编辑)、disentanglement(解纠缠)常用的两种做法:线性探针和PCA_disentanglement和alignment-CSDN博客 在解纠缠的过程中,有一种非常简单的方法来引导G向某个方向进行生成,然后我们通过向不同的方向进行行走,那么就会得到这个属性上的图像。那么你利用多个方向进行生成,便得到了各种方向的图像,每个方向对应了很多