使类和成员的可访问性最小化
规则很简单:尽可能地使每个类或者成员不被外界访问。实例域(非final)决不能是公有的。当需要暴露出不可变的实例时通常会把这个实例做成不可变或者是把这个实例变成私有,同时提供该实例的备份。
在公有类中使用访问方法而非公有域
这就是常说的getter和setter方法,提供给包外访问时提供必要的方法,限制客户端的行为,以便于将来可以在内部改变表示方法。
使可变性最小化
不可变的类比可变类更加易于设计、实现和使用。它们不容易出错,且更加安全。为了使类成为不可变,要遵循下面五条规则:
1.不要提供任何会修改对象状态的方法;
2.保证类不会被扩展(防止子类化去改变类的状态,一般使类成为final)
3.使所有的域都是final的
4.使所有的域都成为私有的
5.确保对于任何可变组件的互斥访问
不可变对象本质上是线程安全的,它们不要求同步。
复合优先于继承
由于超类在未来新的发行版本做出修改,如果子类在这时和超类发生了冲突,那将无法通过编译,这里我们会引入复合的概念。复合既是把需要用到的超类封装到一个新的包装类,包装类的成员中包含了这个需要使用的超类,这样使得该包装类保留了超类的功能特性,同时也提供了包装类后续继承的扩展性。
要么为继承而设计,并提供文档说明,要么就禁止继承
这点只是为了说明,继承应该有严格的功能说明,文档说明超类完成了哪些工作,要求子类在覆盖超类需要遵循的原则,如果编写的类并没有为了后续继承考虑,那么该类应该不允许被继承。
接口优于抽象类
因为Java只允许单继承,抽象类作为类型定义受到了极大的限制。为了实现抽象类定义的类型,类必须成为抽象类的一个子类,在灵活性上会有很多限制。而接口则不同,现有的类可以很容易通过实现新的接口来更新。
接口只用于定义类型
当类实现接口时,接口就充当可以引用这个类的实例的类型。因此,类实现了接口,就表明客户端可以对这个类的实例实施某些动作。为了任何其他目的而定义接口是不恰当的。常量接口模式是对接口的不良使用。
类层次优于标签类
其核心思想是把冗长的超类逐级拆解为可读性更强的多级子类实现,把每个具体实现类保留自己特性需要使用的代码域。
用函数对象表示策略
在Java中具体用到的地方有类似集合中的排序器,排序器对象只表示了排序的策略,这样的类实例在功能上没有区别,互相等价,适合作为单例存在,节省不必要的对象创建开销。
优先考虑静态成员类
静态成员类是最简单的一种嵌套类。如果成员类不要求访问外围实例,就要始终把static修饰符放在它的声明中,使它成为静态成员类,而不是非静态成员类。如果省略了static修饰符,则每个实例都将包含一个额外的指向外围对象的引用。保存这份引用要消耗时间和空间,并且会导致外围实例在符合垃圾回收时却仍然得以保留。