软件构造系列学习笔记(4.1)————面向可理解性的构造

面向可理解性的构造

第1章:构造的多视图与质量目标 ;
第2章:构造的过程 ;
第3章:用ADT和OOP构造软件;
本章:关注internal quality的一种——可理解性。

目录

  • 可理解性的度量
  • 在源代码中记录
  • 编程之前的伪代码
  • 编码规范

可理解性的度量

代码的可理解性可以理解为代码的可读性。具体来说,可从以下几个方面来看:

  • 是否遵循特定的命名规范?
  • 是否足够的注释/说明?
  • 是否足够的内聚性?
  • 方法是否太长或太短、是否容易理解?

难以理解的代码通常意味着代码难以维护、可能隐含更多的错误。

为什么可读性很重要?因为相比起写新代码来说,程序员的大部分时间都用来阅读并修改已有代码。来看下面两个栗子。

Example #a
z = ((3*x^2) + (4*x) – 5) – ((2*y^2) – (7*y) + 11) / ((3*x^2) + (4*x) – 5);
Example #b 
a = ((3*x^2) + (4*x) – 5);
b = ((2*y^2) – (7*y) + 11);
z = (a – b) / a;

尽管a和b都可以被我们看懂,但显然b更容易被人理解,或者说可读性更强。

下面介绍几种度量方式

代码质量测量:WTFs / min

这里写图片描述

简单来说,好的代码让人更容易理解,其他程序员在阅读时就会发出更少的WTF(What the fuck)来抱怨你的代码质量,而不好的代码则更加让人暴躁抓狂。

标识符的长度

标识符的长度包含类名、变量名、方法名等的长度。主要看以下方面

  • 是否具有自描述性?不看注释就可以理解其含义
  • 是否足够简洁?太长的变量名降低效率

度量方式:所有标识符的平均长度。

命名独特性比例(UNIQ)

当两个实体名称相同时,它们可能会混合在一起。 UNIQ衡量所有名字的独特性。在许多地方使用相同的名称是可以接受的。 然而,这个名字应该是指同样的逻辑事物。

代码复杂度和代码行数

复杂的代码不可能被理解。
一个方法越长,它可能越难理解。

注释的密度(百分比)

代码中的注释越多,阅读和理解越容易。

如何写出可理解性好的代码

  • 遵循命名规范
  • 限制代码行的最大长度、文件的最大LoC
  • 足够的注释
  • 代码有好的布局:缩进、空行、对其、分块、等。
  • 避免多层嵌套—增加复杂度
  • 文件和包的组织

代码的可读性/可理解性很多时候比效率/性能更重要,不可读、不可理解代码可能蕴含更多的错误。 因此先写出可读易懂的代码,再去逐渐调优!

在源代码中记录

代码应“自描述” ,最好的代码,即使不加注释也很容易读懂。否则, 增加注释,解释“为什么这么编码” 。

代码中的四中注释
  • 标题注释
    引入了一个类定义,一个重要函数,一个宏定义包,一些其他非平凡模块或整个源代码文件。对于专有程序,标题评论通常包含版权声明。
  • 介绍性注释
    描述类,功能或其他模块的用途和用途。
  • 块注释
    描述了一组相关陈述的目的和策略。
  • 单行/尾随/行尾注释
    解释单个陈述或甚至陈述的一部分。

标题注释和介绍性注释也被称为文档注释,因为JavaDoc可以从这些注释中自动生成。

Commenting conventions

写注释通常有以下几条规约。

  • 在每个文件的开头,应该有一个注释来解释这个文件在项目中的用途。
  • 每个类声明都应该有一个注释来解释这个类的用途。
  • 每种方法或函数都应该有注释来解释它的功能和工作原理,以及它的参数的目的。
  • 所有变量声明,最重要的是类数据成员,都应该附加一个描述其角色的注释,除非其名称明显。
  • 在长函数中使用精细算法的情况下,应使用内联注释来突出显示和解释算法的所有重要步骤。

编程之前的伪代码

用伪代码表达某个模块/算法的内部处理逻辑/流程。写伪代码也有如下规约。

  • 声明以简单的英文书写。
  • 每条指令都写在一个单独的行上。
  • 关键字和缩进用于表示特定的控制结构。
  • 每套指令都是从上到下书写的,只有一个入口和一个出口。
  • 陈述组可以形成模块,并且该组给出名称。
六项基本电脑操作
  • 从外部接收信息:Read,Get
    这里写图片描述
  • 把信息传到外面:Print, Write, Output, Display, etc
    这里写图片描述
  • 执行算术/计算:Compute, Calculate
    这里写图片描述
  • 将值分配给变量或内存位置:Set, Save, Store, <-
    这里写图片描述
  • 比较并选择其他操作:If-Then-Else
    这里写图片描述
  • 重复一组操作:For, While, Do/Until
    这里写图片描述

编码规范

选择何种编码风格是程序员个人的自由,但要做到: (1) 在所有地方保持一致的风格;(2) 遵从团队的统一编码风格。

编码规范:定义了一系列的规则,按这些规则进行编码,有助于提升代码可读性,例如——
命名、代码布局/缩进、数据声明方式、文件组织方式 、etc。

编程规范涉及到许多方面,下面展开来说。

命名

变量,函数或类的名称应告诉你,它为什么存在,它做了什么以及如何使用它。
如果名称需要注释,则该名称不会显示意图。

int d; // elapsed time in days 
int elapsedTimeInDays; 

需要注意以下几点:

  • 避免造假:避免留下模糊代码含义的虚假线索。例如仅当accountList实现List时才使用accountList; 其他情况下accounts更好。
  • 做出有意义的区别
  • 使用可发音名称
  • 使用可搜索的名称

包名称应该是小写的;类和接口名称应该是名词和大写;方法名称应该是动词并以小写开始;常量命名:所有大写字母之间带下划线;参数命名,确保你的参数意味着什么。

垂直格式化:空行

这里写图片描述

垂直密度意味着密切关联,因此密切相关的代码行应该垂直密集。密切相关的概念应该保持垂直相互靠近。 他们的垂直分离应该衡量每个人对另一个人的可理解性有多重要。

横向格式化:空格

我们使用水平空白区域来关联强烈关联的事物,并将与强调它们的关系更加微弱的事物分开。

横向格式化:缩进

代码必须根据其嵌套级别进行缩进。你可以选择缩进量,但应该保持一致。不好的缩进会使程序难以阅读,也可能成为一个难以理解的错误来源。

横向格式化:换行

当一个表达式不适合单独一行时,根据以下一般原则将它换行:

  • 逗号后换行
  • 在操作符前换行
  • 将新行与上一行中相同级别的表达式的开头对齐。
文件组织

在源文件中的顺序:

  • 包或文件级别的注释
  • 包和导入的说明
  • public的类和接口的声明
  • private的类和接口的声明

导入说明的顺序:

  • 标准包(java.io, java.util, etc
  • 第三方包(例如com.ibm.xml.parser
  • 你自己的包

类部分的顺序:

  • Javadoc 注释
  • 类声明的说明
  • 整个类的注释
  • 类静态变量声明(public,protected,package,private)
  • 类实例变量声明(public,protected,package,private)
  • 函数声明(构造函数优先)

Principles of Package:

  • 复用/发布等价原则(REP)
    复用的粒度应等价于发布的粒度
  • 共同封闭原则(CCP)
    一个包中的所有类针对同一种变化是封闭的;一个包的变化将会影响包里所有的类,而不会影响到其他的包;如果两个类紧密耦合在一 起,即二者总是同时发生变化,那么它们就应属于同一个包。
  • 共同复用原则(CRP)
    一个包里的所有类应 被一起复用;如果复用了其中一个类,那么就应复用所有的类

Principles of Package Coupling:

  • 无圈依赖原则 (ADP)
    不允许在包依赖 图中出现任何圈/回路;无圈将容易 进行测试、维护与理解;若存在回路依赖,很难预测该包的变化将会如何影响其他包。消除圈的两种方式:创建新包和利用DIP<依赖倒置原则>和ISP<接口隔离原则>。
    (1)创建新包
    这里写图片描述
    这里写图片描述
    (2)利用DIP<依赖倒置原则>和ISP<接口隔离原则>
    这里写图片描述
  • 稳定依赖原则(SDP)
    包之间的依赖关系只能指向稳定的方向;被依赖者应更稳定于依赖者;稳定的包较难发生改变;如果不稳定的包却被很多其他 包依赖,会导致潜在的问题。
    这里写图片描述
  • 稳定抽象原则(SDP)
    在稳定性与抽象度之间建立关联;一个包是稳定的,那么它就应该尽可能抽象;一个完全稳定的包中只应包含抽象类;不稳定的包应是具体的,以便于容易的进行修改。

SAP和SDP共同构成了包之间的“ 依赖倒置原则DIP”;SDP: 依赖应指向稳定的方向,SAP: 稳定性隐含着抽象;因此,依赖应指向抽象的方向。

使用CheckStyle

Checkstyle是一种开发工具,可帮助程序员编写符合编码标准的Java代码。Checkstyle高度可配置,可以支持几乎任何编码标准。您可以在Eclipse IDE中使用Checkstyle命令行(作为插件),在Ant,Gradle,Maven等构建工具中以及在持续集成工具中使用,如Jenkins。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值