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

实例域绝不能是公有的。包含公有可变域的类并不是线程安全的。

公有的静态final域可以来暴露常量,但是一定要注意不能包含指向不可变对象的引用。

类具有公有的静态final数组域是很愚蠢的,客户端将能够修改数组的内容。

15. 在公有类中使用访问方法而非公有域

16.使可变性最小化

为了使类成为不可变,要遵循下面五条规则:

  1. 不要提供任何会修改对象状态的方法
  2. 保证类不会被扩展 3.使所有域都是final的 4.使所有的域都成为私有的 5.确保对于任何可变组件的互斥访问:永远不要向客户端提供对象的引用来初始化域。可以采用“保护性拷贝”技术

实现方法:让类的所有构造器都变成私有的或者包级私有的,并添加静态工厂来代替公有的构造器。

如果选择让自己的不可变类实现序列化接口,并且包含指向可变对象的域,则需要显示的提供readObject和 readResolve方法

总之,在实际中尽可能把类做成是不可变的,能使用final就尽量使用final;构造器应该创建完全初始化对象,建立起所有的约束关系。

17. 复合优先于继承

同个包内合理的设计,来通过继承是比较安全的(但仍然有风险)。跨包继承则很危险。

超类在后续发行中修改了功能,会导致子类功能的异常。避免这样的情况就是采用复合。新类中通过一个私有域引用现有类的一个实例,这称为复合。现有类添加新方法也不会影响新类。这样设计得到的类会更加稳固。

只有当两个类确实存在 is-a关系的时候,才适用继承。注意不要盲目的使用继承。

17.要么为继承而设计并提供文档说明,要么就禁止继承

在做继承时要写完善的文档。

为了继承而设计的类,唯一测试方法就是编写子类。

18. 接口优于抽象类

使用设计接口要谨慎,一旦发行和大量实现,就肯定无法再修改了,而抽象类确可以。

19. 接口只用于定义类型

避免使用常量接口(接口里面定义大量常量)。应该使用枚举类型或者不可实例化的工具类来导出这些常量。
总结:不要使用接口来导出常量。

20. 类层次优于标签类

充斥样板代码、标签类的域就是标签类。例如一个Point类就是一个标签类。利用抽象类抽象出一些共用的方法。

21. 用函数对象表示策略

即策略模式。一些策略(例如比较功能),需要设计一个策略接口,再设计一个策略实现类,来供其他类调用。

22. 有限考虑静态成员类