Mike Zhang

DNS DevOps CISSP CISA Security+ 摄影 程序员 北京

《代码整洁之道》读书笔记

04 Aug 2018 » program

注释的使用

程序员应当将注释保持在可维护,有关联的高度,同时如果可以写出清楚的代码。直接无需编写注释会更好。不准确的注释比没有注释更糟糕。代码在不断的变化,但是很多情况下,注释却被忘记修改。

  1. 好的注释使用方法
  • 法律信息: 放置在代码头部的一些标示信息,版权信息等。
  • 提供一些基本的信息注释,但是同时如果可以使用函数名等表达清楚就减少注释的使用
  • 提供代码编写的意图,让别人知道代码为什么这么写
  • 提供警告等信息,特别是一些函数的执行可能会导致不期待的后果。
  • TODO注释,提供代码编写的备注,用于将来继续实现的功能点。
  1. 糟糕的注释使用
  • 误导性注释,注释没有解释清楚代码的执行逻辑和意图。 – 循规式注释,代码规范或者编写要求,会导致一些注释的多余比如每个函数多需要写注释,Go语言就要求公共访问的代码需要编写注释。 – 无用的注释,比如注释和函数名几乎一样,/* the name */ 和 private String name – 代码的署名(版本系统中已经包含,查看可能更简单) – 注释掉的代码 担心未来继续使用(版本软件可以管理) – html 注释 比如提供页面展示需求 – 大量的信息(比如加入rfc注释) – 注释位置与代码不直接相连

代码格式

程序员应该保持良好的代码格式,选择一套完整的管理代码格式的规则,贯彻下去,如果在团队中,则应当一致同意采用一套简单的规则样式,所有成员都需要遵循。

代码格式关乎沟通,而沟通才是专业开发者的头等大事。

代码文件的大小应该保持在一个合理的范围内,比如200行以内,较短的文件比长文件更加易于理解。就像报纸一样,读代码应该尽量自顶向下的,且彼此(函数体或者声明)保持一个合适的范围,垂直方向上相互关联的代码保持紧密,且每一部分独立的代码保持分离。

团队规则应该保持一致,应该在任何项目开始时候明确编码的规则,一直沿用下去,保持一致和顺畅的风格能使得代码在阅读和沟通的时候保持顺畅。

代码的行数应该保持在120个字符以内,这样在阅读代码的时候,无需进行手动的移动视图既可以查阅代码,同时代码的。 代码的水平对齐,使用一些格式化的代码工具,可以很容易实现对齐,一般是变量声明的对齐。缩进的使用可以减少代码的阅读量,对于块级别的代码可以一扫而过,结构也更加清晰。

对象和数据结构

私有变量以及对于变量的取值和赋值操作,并非简单的用于操作数据,应该考虑如何实现抽象层次,简单的取值和赋值与公有变量没有差别。 更多的是应该考虑如何实现对象和数据结构的封装与抽象,使得用户无需理解数据的结构和定义,就可以操作数据,实现更简洁的接口操作。如下的代码, 第二种形式将抽象做的更好,无需理解内部的具体实现。

<br />public interface Vehicle{
  double getFuelTankCapacityInGallons()
  double getGallonsOfGasoline()
}

public interface Vehicle{
  double getPercentFuelRemaining()
}

过程式的代码难以添加新的数据结构,一般需要修改大量的函数实现。面向对象的代码一般比较难以添加新的函数,因为必须修改所有的类。所以在编写函数的时候需要考虑需求,根据需求来编写代码。

一切都是对象只是一个传说

Demeter法则, 指的是模块不应该了解所操作的对象的内部情况, 对象隐藏数据,而暴漏操作。对象不应该通过存取器暴漏内部结构。 逻辑上不直接相关的,不应产生联系。

  • 每一个单元仅仅对其他的单元有非常有限的了解:即联系非常紧密的单元
  • 每一个单元只与他的朋友交互;不要与陌生人说话
  • 只与亲密的朋友交互。 基本原则为:**一个给定的对象,要尽可能少的了解它的结构、属性等等(包括他的子组件),与“infomation hiding”原则一致。

假如有用户,钱包和收银员三个类,如果用户去店里买东西,应当用户去调用钱包的方法操作,而不是收银员直接去调用钱包的方法去获取金钱。 钱包和用户是紧密相关的,其他的不应该直接产生关系。

数据传送对象: 指的是这类的声明中只包含有公有变量没有具体的函数,一般用来定义数据的序列化或者传递数据使用,DTO. 但是有时候也会加入一些简单的封装方法,比如get, 或者print方法等. 对于业务的封装应该独立于DTO实现,使得代码更加简练直接。

其他的相关概念:

  • VO(View Object):视图对象,用于展示层,它的作用是把某个指定页面(或组件)的所有数据封装起来。
  • DTO(Data Transfer Object):数据传输对象,这个概念来源于J2EE的设计模式,原来的目的是为了EJB的分布式应用提供粗粒度的数据实体,以减少分布式调用的次数,从而提高分布式调用的性能和降低网络负载,但在这里,我泛指用于展示层与服务层之间的数据传输对象。
  • DO(Domain Object):领域对象,就是从现实世界中抽象出来的有形或无形的业务实体。
  • PO(Persistent Object):持久化对象,它跟持久层(通常是关系型数据库)的数据结构形成一一对应的映射关系,如果持久层是关系型数据库,那么,数据表中的每个字段(或若干个)就对应PO的一个(或若干个)属性。