使类和成员的可访问性最小化

将设计良好的组件与设计不佳的组件区分开来的最重要的因素是,隐藏内部数据和其他实现细节的
程度。一个设计良好的组件隐藏了它的所有实现细节,干净地将它的 API 与它的实现分离开来。然后,
组件只通过它们的 API 进行通信,并且对彼此的内部工作一无所知。这一概念,被称为信息隐藏或封
装,是软件设计的基本原则

信息隐藏很重要有很多原因,其中大部分来源于它将组成系统的组件分离开来,允许它们被独立地
开发,测试,优化,使用,理解和修改。这加速了系统开发,因为组件可以并行开发。它减轻了维护的
负担,因为可以更快速地理解组件,调试或更换组件,而不用担心损害其他组件。虽然信息隐藏本身并
不会导致良好的性能,但它可以有效地进行性能调整:一旦系统完成并且分析确定了哪些组件导致了性
能问题(条目 67),则可以优化这些组件,而不会影响别人的正确的组件。信息隐藏增加了软件重用,
因为松耦合的组件通常在除开发它们之外的其他环境中证明是有用的。最后,隐藏信息降低了构建大型
系统的风险,因为即使系统不能运行,各个独立的组件也可能是可用的

经验法则很简单:让每个类或成员尽可能地不可访问。 换句话说,使用尽可能低的访问级别,与
你正在编写的软件的对应功能保持一致。

公共类的实例字段很少情况下采用 public 修饰(详见第 16 条) 如果一个实例字段是非 final
的,或者是对可变对象的引用,那么通过将其公开,你就放弃了限制可以存储在字段中的值的能力。这
意味着你放弃了执行涉及该字段的不变量的能力。另外,当字段被修改时,就放弃了采取任何操作的能
力,因此带有公共可变字段的类通常不是线程安全的 。即使一个字段是 final 的,并且引用了一个不可
变的对象,通过将其公开,你放弃了切换到一个新的内部数据表示的灵活性,而该字段并不存在。


同样的建议适用于静态字段,但有一个例外。 假设常量是类的抽象的一个组成部分,你可以通过
public static final 字段暴露常量。 按照惯例,这些字段的名字由大写字母组成,字母用下划线分隔(详
见第 68 条)。 很重要的一点是,这些字段包含基本类型的值或对不可变对象的引用(详见第 17 条)。
包含对可变对象的引用的字段具有非 final 字段的所有缺点。 虽然引用不能被修改,但引用的对象可以
被修改,并会带来灾难性的结果

请注意,非零长度的数组总是可变的,所以类具有公共静态 final 数组字段,或返回这样一个字段

的访问器是错误的。 如果一个类有这样的字段或访问方法,客户端将能够修改数组的内容。 这是安全

漏洞的常见来源:

public static final Thing[] VALUES = { ... };

要小心这样的事实,一些 IDE 生成的访问方法返回对私有数组字段的引用,导致了这个问题。 有两
种方法可以解决这个问题。 你可以使公共数组私有并添加一个公共的不可变列表:

private static final Thing[] PRIVATE_VALUES = { ... };
public static final List<Thing> VALUES =
Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES));

或者,可以将数组设置为 private,并添加一个返回私有数组拷贝的公共方法:

private static final Thing[] PRIVATE_VALUES = { ... };
public static final Thing[] values() {
return PRIVATE_VALUES.clone();
}

  


  


  

 

posted @ 2020-04-06 18:15  webzom  阅读(140)  评论(0)    收藏  举报