本文是罗伯特·马丁(Robert Martin)的“清洁代码”书的提要,也是我对清洁代码的理解的摘要。 没有关于测试,TDD,应采用的体系结构等部分。 这里的一切都与清洁代码应该是什么有关。

是的,也许“清洁代码”的主题已经很老套了,但是,并不是每个人都熟悉它,而且,我还没有遇到文章中包含的类似内容。
一般
没有真正的方法和解决方案。 有一种最适合特定任务的工具。
解决问题时,请尝试重现可能影响此任务的所有情况,并在考虑到所有情况的情况下执行任务。
另外,解决问题时,请尝试从相反的方向进行。 了解最终要获得什么样的结果,并以此为基础制定执行任务的算法。
发送任务以释放之前,请检查其是否正常运行。 是否有任何错误。 这甚至适用于发送到您的分支的那些提交。 最理想的情况是没有人能发现您开发的功能中的错误。
始终想一想如何使您的代码更简单,更简洁,更易读。
- 任务可以有哪些情况?
- 我是否考虑到了一切?
- 可能出什么问题了?
- 可以结合什么?
- 有没有类似的功能?
- 这里多余的是什么?
- 如何使其更容易?
- 如何使其更具可读性?
- 如何使它更清晰?
干净的代码
如何编写干净而良好的代码? 就像写书一样。 首先,您草拟了一份草稿,然后将其梳理成您很高兴阅读的状态。 永远记住,您的代码必须讲一个故事,以便读者可以理解。
可以理解实体-接口,类,方法,变量,对象等。
- 简洁的代码简单,富有表现力,并且专注于特定任务。
- 简洁的代码像散文一样易于阅读。 如果不是这种情况,则值得重构。
- 干净的代码易于修改。 它不应严格地与实体堆联系在一起。 任何实体都可以轻松更改。
- 干净的代码通过审查要好得多。 如果评论中有很多评论,那么它并不干净,需要重构。
- 干净的代码看起来好像已经处理了很长时间。 无论您以何种方式对其进行改进,您仍然可以得出结论,该代码是最好的。 因此,干净的代码被认为是最小的细节。
- 侦察员规则:保持停车场清洁干净。 这很容易转向编程。 看到肮脏的代码了吗? 解决问题时,请使其更清洁。 您不要为此而烦恼,如果脏代码很脏,那么应该分配一个单独的任务和时间来清理它。
- 不要害怕进行更改。 如果您想制作它们,那么您就有理由这么做,这意味着您将使代码更好,更简洁。 此外,测试将显示您的代码中是否存在任何错误(假设它们完全存在)。
- 任何实体都应仅对一项职能负责。 她必须表现出色。 单一责任。
- 如果一个实体立即负责两个或多个动作,则其功能必须分开。
- 该代码应从上至下阅读。
- 在一个优秀且称职的架构中,无需花费大量成本和精力即可进行更改。
- 删除无效代码。 无效代码是在任何情况下都不会调用的代码,或者在任何地方都不会使用的代码。
名称和部门
- 为任何实体使用清晰易读的名称。 他们应该说明该实体存在的原因,作用和使用方式。
- 不要害怕浪费时间选择最好和友好的名称。 通过工作或阅读此代码,您将来会取胜。
- 如果实体的名称与其功能不符,或者该名称不了解实体的功能,则必须将其重命名为最易理解的名称。 如果这不可能,则说明其功能存在问题,需要对其进行重构。
- 名称为“ And”,“ With”的实体违反了单一职责。 此类实体的功能值得共享。 但是这个规则有时会被忽略。
- 难以理解的文本,应将行放入变量中并给它们明确的名称。
- 方法名称必须包含一个动词,该动词描述此方法的作用以及此方法使用的关键字。 如果方法的名称没有动词,则此实体不应是方法,或者必须给其指定正确的名称。
- 出于两个不同的目的,应避免使用相同的名称。
- 如果一个实体的名称与另一个实体的名称相似,那么它们的功能很可能非常相似,需要合并吗? 如果不是,则需要更改其名称,以使它们不相似。
- 如果您在阅读代码时从心理上重命名了一个实体,以便可以更清楚地了解其功能,则将其重命名为该别名。
- 为一个概念选择一个词。 当您获取,检索和获取名称时,将很难理解其功能。 更好的去处。
- 一个简短易懂的名字比一个简短但不易理解的名字更好。
功能介绍
- 功能应简短而紧凑。
- 功能应该非常简短和紧凑。
- 大约最多20行,一行中最多150个字符,如果不合适,则需要分开。
- 一个功能只能执行一个操作。
- 她必须做得很好,而且别无其他。
- 如果一个功能仅执行处于相同抽象级别的那些动作,则该功能将执行一个操作。
- 要确定一个功能是否执行多个操作,请尝试从中提取另一个功能,这将不是实现的简单重构。
- 任何通过switch-case,if-else进行长时间选择的条件语句都应拆分或合并而不进行重复,可能会合并到带有实现的类中,并将实现的选择转移给基类,工厂或其他人。
- 如果,否则,等等。 必须包含对一个函数的调用。 它将更具可读性,更清晰,更容易。
- 一个函数的理想输入参数个数=0。如果输入参数多于三个,则值得考虑如何最好地消除它们,例如,为这些参数创建一个类。
- 输入的参数越多,函数的理解就越困难。
- 传递参数实参的函数(函数的操作依赖于该函数)指示该函数执行多个操作。 此类功能应分为两个级别,并称为更高级别。
- 修改输入自变量的函数必须提供对已更改对象的引用,而不仅仅是在不返回的情况下对其进行修改。
String transform(String text)
- 如果函数必须更改输入参数,则让它更改其所有者对象的状态。
- 如果函数的输入参数不应更改(并在代码中进一步使用),则应复制参数的值并使用函数内部的副本进行操作。
- 与其返回null,不如使用一个空对象
Collection.empty()
或一个空对象EmptyObject()
。 - 始终尝试使用非静态功能。 如果不可能,请使用static。
- 如果有一个代码应该一个接一个地跟随,则将第一个函数的结果传递给第二个函数,以使某人不会更改调用顺序。
- 使用多态性代替if / else或switch / case或when。
- 避免负面条件。
留言
- 如果可以使用函数或变量,请不要使用注释。
- 不要评论错误的代码-重写它。 不值得解释不良代码中会发生什么,最好使其清楚易懂。
- 注释可用于传达一些信息,有关后果的警告,但不能解释代码的工作方式。
- 在需要注意代码需要改进的情况下,请使用TODO和FIXME,但是现在没有相关资源。
- 使用
//region REGIONNAME //endregion REGIONNAME
,如果使用,请考虑是否可以将区域划分为实体。 - 复杂但干净的文档代码。
- 不要留下旧的注释掉的代码。 如有必要,您可以在提交历史中找到它。
- 评论应简洁明了。 信息注释不应包含太多信息。 一切都应该简短明了。
- 遵循项目采用的代码样式。
- 遵循团队接受的规则。
- 根据格式和代码样式,代码将更易于阅读和更好。 出版之前将这本书交给编辑是没有白费的。
- 您需要有自动工具来为您格式化代码。
- 源文件应该像报纸上的文章。 有一个标题,以参数的形式进行简要说明,以功能的形式进行内容说明。 如果不是这种情况,则应更改格式。
- 例如,在一个包中,彼此相关的实体应该是紧密的,以便更轻松地浏览代码。
- 类变量(字段)必须位于类的顶部。
- 方法变量应更接近其使用位置。
- 函数必须按调用顺序排列。 如果一个调用另一个,则调用函数必须在被调用函数之上。 另一方面,较低级别的私有函数可能位于文件的底部,并且不会干扰对高层代码的理解。 但是我更喜欢第一种方式。
对象和数据结构
- 您必须使用抽象,以便可以轻松更改实现。
- 您应该使用抽象,因为使用该功能的客户端不应该了解实现细节,因此他应该知道在哪种情况下使用哪个实现。
- 您必须提供您应该使用的API,并隐藏实现细节,结构。 因此,使用此类实体并添加新类型的行为,功能和实现将更加容易。
- DTO-数据传输对象。 一个仅包含数据而没有功能的类。 为了传输一些数据是必要的。 此类的对象必须是不可变的。
班级
- 类必须紧凑。
- 类应该更加紧凑。
- 班级名称应描述其职责。 从这里您可以计算类的大小。
- 该类的功能必须清楚地对应并适合该类的名称。
- 将连接性分成小类。 不应存在僵化和丰富的凝聚力-这会使项目的支持和开发复杂化。
- 记住单一责任。 一个实体必须有一个而且只有一个改变的理由。
- 观察封装。 弱化封装应该永远是最后的手段。
- 通常,我们将变量和辅助函数声明为私有,但有时需要声明它们为受保护并能够从测试中访问它。
- 如果一组功能属于某个功能,则可以并且应该将这组功能分配给单独的类并使用其实例。
错误处理
- 使用异常而不是返回错误代码。
- 错误处理是一项操作。 如果函数中有
try
关键字,则在catch/finally
块之后,函数中不应再有其他任何内容。 - 如果您有一个列出错误的枚举,则最好摆脱它,而改用异常。
- 使用未经检查的异常来明确指出存在问题的位置。 无需捕获此类错误,而是需要编写代码以使该错误永不存在。
- 传递足够的信息以及引发异常,以便以后的代码用户可以了解实际发生的情况。
- 代替带错误处理的条件语句,最好抛出异常并对其进行处理。
- 不要在任何地方传递null。 尽量避免这种情况。
- 错误处理是一项单独的任务,不适用于程序的主要逻辑。
边框
- 我们总是使用某些库,这些库通常给我们提供太宽泛,太小的功能或与预期的功能冲突,这使代码在最终使用时更加混乱。 您可以通过简单地应用装饰器,适配器,外观等模式来避免这种情况。
- 在某些情况下,您需要使用正在开发中的功能或尚未适应生产代码使用的功能。 在这种情况下,您应该想象您对库/此功能的期望,并编写您的界面或创建一个实体,以您需要的方式在项目中使用该实体。 库完成并变得稳定后,您可以将其调整为适用于现成的结构并使用现成的功能。
后记
本文仅提供有关编写干净代码的准则。 当然,它们可以忽略。 您只需要了解,您的任何决定都应有支持该决定的论点。