本篇文章3319字,读完约8分钟

编者按:本文介绍了组织代码的四种策略:组件组织法、工具箱组织法、层次组织法和类别组织法。这四种策略形成了一定的层次,每种策略都针对不同类型的代码内聚,可以说是包罗万象。

组织代码的原因和定义

至于如何开发程序,你得到的大多数建议基本上都是教你如何组织代码,这与计算机技术无关。这是一件非常有趣的事情。

就计算机本身而言,耦合和内聚基本上是独立的。计算机不在乎你是把所有的代码放在一个文件里,还是按字母顺序分类,或者用单个字母来命名所有的变量。合理组织代码的目的不是让计算机理解您的代码,而是让其他人很好地理解您的代码,以便高效、自信地维护代码,并在一定程度上进行二次开发。

应该编写代码,以便其他人可以先阅读,然后机器才能执行

-"计算机程序的结构和解释"(由阿贝尔森和苏斯曼)

当一段代码写得太长,包含太多的元素时,它会变得非常复杂,人们很难定位信息和概览,也很难清楚地理解代码每个部分的功能。解决这个问题的最好方法是“分而治之”——将复杂的大代码分成几个小部分,每个部分都可以独立理解。

对于类,这种方法可以帮助我们创建具有强内聚性的逻辑对象,并且它也适用于领域模型。对于单独编译的项目,我们必须消除循环依赖,并确保项目之间有逻辑和稳定的接口。在工程和类(java中的包或c#中的空)之间的层次上,有许多不同的代码组织方法。根据我自己的经验,许多开发人员在没有太多考虑的情况下选择了一种组织代码的策略,但是他们不明白为什么他们应该使用选择的策略。

关于如何高效地组织代码 我只说这四招

本文介绍的前三种策略适用于类、包和工程级别的代码组织,而最后一类组织策略或多或少是特定于包级别的代码组织的。

1.成分的有机法则

组件组织法可以最小化代码的复杂性,它主要关注代码单元(如包)的外部内聚和内部内聚。外部内聚意味着包具有最少数量的接口,接口的功能与组件提供的服务密切相关;内聚意味着包中的代码具有很强的内在关联性。

完全独立的电子元件

至于一个好的代码抽象应该包含什么,这个主题可以引出许多文章,现在许多文章已经介绍了这个问题。如果我们在这里讨论代码抽象的原则,即使只涉及到问题的一小部分,这篇文章也会太长。可以说,从代码抽象开始的最好方法是学习坚实的原则。

在学习过程中,练习和思考每个过程的原理是非常重要的。在本文中,我将根据自己的实践经验,只介绍代码库复杂性急剧增加的最常见原因之一。许多人确实试图通过基于代码库的“分而治之”的方法来组织代码,但是最终未能将包分解成组件。

为了创建一个新的代码单元,通常的做法是识别一个或多个现有包中的一些函数,并生成一个新的抽象。这意味着代码单元的总数增加了,相应地每个代码单元的容量也减少了,使得代码更容易理解和消化。然而,这只是第一步,整体复杂性并没有降低。接下来,我们需要消除依赖性。

在我看来,具有相互依赖性的包不能被认为是独立的代码单元,因为只看包的内容不能完全理解它的代码。在上面的示例中,可以直观地看到,图形类与图形存储类相关联,并且图形存储类不允许被修改。图形存储包不仅依赖于许多图形包的域模型,而且它们之间也有依赖关系。最容易消除的依赖通常是新创建的包对旧包的依赖:

关于如何高效地组织代码 我只说这四招

这是一个改进的最重要的原因是,当我们读取存储代码时,我们可以确保代码函数中涉及的所有对象都包含在可存储接口中。

客户端不应该依赖它不需要的接口。

-接口隔离原则

下一步是消除图形包和存储包之间的直接关联。例如,消除关联的一种方法是在图形包中创建一个图形持久化器接口,以便更高级别的包可以与图形包接口。这样做的最大好处是图形包所依赖的存储包的功能变得清晰。

这个过程在理论上听起来很简单,但是要确定合适的组件和分离策略需要大量的工作。通常,您会发现提取的抽象在过程中是不正确的,您所做的所有更改都必须被推翻并重新开始。然而,合理分离组件的回报是巨大的,你可以得到易于理解的代码,并且代码可以简单地升级、测试和重用。

2.工具箱组织法

工具箱的有机法则侧重于外部内聚,它提供了一个稳定的工具箱,用户可以从中选择他们需要的东西。使用这种策略的前提是代码具有很强的内聚性。工具箱通常由接口的互补执行机制组成。用户可以选择所需的执行机制或组合多个执行机制,但在一次执行时,他们不会同时使用多个机制。

馆藏库的组织方法是一种典型的工具箱组织法则,它涉及一系列馆藏接口的互补执行机制。这些收集接口的特性受时间复杂度、内存占用和其他因素的影响。工具箱也可以有一个统一的主题,比如只包含基于磁盘的数据结构。

日志库本身不一定是一个工具箱,但它通常包含一个日志编写器工具箱。

正是因为用户可以方便地使用工具箱,而且工具箱中的每个“工具”都不够大,不足以授权自己的代码单元,所以工具箱得到了发展和完善。图形用户界面库中的每个组件可能都有自己的包,但是如果为每个组件构建一个项目,就会造成不必要的浪费。

类似地,每个集合实现可能适用于一个单独的包,但是将它们放在不同的包中会产生大量的冗余。但是,在本例中,为了根据外部一致性原则保持外观简单,包含几个类的集合实现需要有自己的包。

3.层级组织法

层组织法的重点主要是促进工作流的内聚性,而不是通过最小化跨单元耦合项来降低代码的复杂性。它根据部署方案和其他规则划分层的边界,然后划分代码。这种策略不同于工具箱的有机法则,各层之间没有最小的连贯界面。层接口有很多组成元素,用户层对应的组成元素可以访问。

跨层组件耦合项

层组织法则的典型特征是,跨层的逻辑元素之间的逻辑耦合比同一层内的逻辑元素之间的逻辑耦合更强。当这个策略失败时,最常见的情况是当实现代码组织时,需要跨所有层创建文件,这是教科书中定义的一个紧密耦合的例子。

给定两个代码单元a和b,当a改变时,b也必须改变,所以a和b是耦合的。

——c2 wiki中的定义

在这种情况下,逻辑元素中的依赖关系通常会使多个解耦的层成为一个非常复杂的单元。

在实践中,我们应该谨慎地使用层组织方法,因为层组织策略通常会提高而不是降低系统的整体复杂性。然而,在某些情况下,层组织法带来的好处远远超过它的缺点。在这一点上,尝试在用户代码中的一个地方隔离层依赖是值得的。

4.类别组织法

类组织法则适用于对过于复杂的代码单元进行分类,即基于类或接口类将不同的代码部分放置在相应的桶存储单元中。在这个分类过程中,依赖、概念连接和一些典型的生成包(通常命名为异常、接口、管理器、助手、实体等。)被忽略。

类别组织法与工具箱组织法的不同之处还在于,它摒弃了一些表面的东西,例如,包中的补充类和可互换类可以形成一个合理的库。据我所知,没有人主张用类别组织法来组织不同类别或项目的代码。

按类别组织的工程组织法

我认为类组织法不适合组织代码,因为它隐藏了复杂代码的实际问题,会误导开发人员以为代码中的问题已经解决了,但实际上问题还没有完全解决,整体复杂度也没有降低。类别组织策略的另一个大缺点是,在极端情况下,每个类别都可以被分成一个精确的类别。我遇到过这种极端的情况。为了使所有的代码都有一个匹配的包,在整个代码库中创建了一些奇怪的东西,比如代码管理器、助手等等。

关于如何高效地组织代码 我只说这四招

我认为类别组织法是一种“代码趣味”,但从我个人的经验来看,类别组织法被广泛用于组织商业软件的代码(主要是用java或c#编写的)。阶级组织法提供了一个划分大包裹的简单方法,但是对于大多数人来说,包裹的大小并不是主要矛盾。类组织法成功地解决了代码部分的独立性问题,因此它经常被用在商业软件开发中。

摘要

组织代码是软件开发人员的核心技能。和其他技能一样,提高的最快方法是仔细思考你为什么放弃先前的选择。组织代码有许多不同的策略,最重要的是要学会区分这些策略中哪些是有效的,哪些是危险的。

Infoq是一个有内容的技术社区。这篇文章最初发表在infoq微信公众账号,标识:infoqchina。(点击此原始链接)请联系微信:infoqzone。

原文作者:infoq技术媒体,如有转载,请注明出处:http://36kr/p/5045182

“读完这篇文章还不够吗?如果你也开始创业,希望你的项目被报道,请点击这里告诉我们!”

标题:关于如何高效地组织代码 我只说这四招

地址:http://www.j4f2.com/ydbxw/10404.html