Clean Code – Class

By | 2019年6月2日

1. 类的组织

变量定义在class头部,顺序如下:

  • 公共静态常量 – public static
  • 私有静态常量 – private static
  • 私有实体变量 – private

变量列表之后定义方法,顺序如下:

  • 构造方法 – constructor
  • 公共静态方法 – public static: 其调用的私有静态方法,出现在该方法之后。
  • 公共方法 – public:其调用的私有方法,出现在该方法之后。

封装

我们喜欢保持变量和工具函数的私有性,但并不执着于此。我们也需要protected或无修饰符的变量或工具函数,好让测试可以访问到。

对我们来说,测试说了算。如果某个测试需要调用一个函数或变量,我们就会将该函数或变量设置为protected或package内可访问的。

2. 类应该短小

类应该多短合适呢?对于函数,我们通过代码行数衡量大小。对于类,我们通过职责(Responsibility)来衡量。

2.1 单一职责原则

单一职责原则:类或模块应该有且只有一条加以修改的理由,既类的修改动机只有一个

许多开发者害怕数量巨大的短小而职责单一的类会导致难以一目了然抓住全局。他们认为,要搞清楚意见较大工作如何完成,就得在类与类之间找来找去。

然而,有大量短小类的系统并不比有少量庞大类的系统拥有更多移动部件,其数量大致相等。问题是:你想把工具归放到有许多抽屉、每个抽屉装有定义和标记良好的组件的工具箱中呢,还是想要少数几个能随便把所有东西扔进去的抽屉?

职责多的巨大类的系统,总是让我们在目前不需要了解的一大堆东西中艰难跋涉。

2.2 内聚性

类应该只有少量实体变量,类中的每个方法都应该操作一个或多个类变量。通常而言,方法操作的变量越多,就越粘聚到类上。

内聚性,意味着类中的方法和变量互相依赖、互相结合成一个逻辑整体。

2.3 保持内聚性就会得到许多短小的类

拆分大函数,将会导致更多类的出现。从较大函数抽取新函数时,需要传入四个变量,这个有必要吗?

完全没必要,只要将四个变量提升为类变量(field),就不用传递变量了。

可惜这样就丧失了内举性,因为堆积了越来越多职位少数函数共享而存在的实体变量。等一下!如果有些函数想要共享某些变量,为什么不让它们拥有自己的类呢?

当丧失类内举性,就拆分它。所以,将大函数拆分为许多小函数,往往也是将类拆分为多个小类的时机。

原书中,作者举了个例子。有一个很长的main函数,从中拆分出两个类,拆分出来的类中当方法都很短。拆分后的main方法,短了很多,可读性大大增强。代码太长,就没贴上来。