使类和成员的可访问能力最小化
一个好的API,它的接口是应该和内部实现完全隔离开的,一个模块不需要知道其他模块的内部情况,这个概念叫做“封装”,这么做的好处是能大幅度降低类之间的耦合程度,可以使得这些模块进行独立的修改,而不用去考虑对其他部分的影响。
Java中有四种访问级别的关键字,可访问性从低到高分别是private,protected,默认和public,理论上来说,凡是没有理由公开在外部接口的方法和变量,都应该表明为private。
支持非可变类
非可变类的对象一旦被创建就不能再被修改了,这样的好处体现在:
- 可以提高一定的效率,如果你知道一个对象是不可变的,那么需要拷贝这个对象内容的时候,就不用全部复制而只是复制地址;
- 对于多线程是安全的,因为对象本身不可以被修改;
降低一个对象中存在状态的数目,可以更容易的分析出该对象的行为,同时降低出错的可能性;
一个非可变类的五条规则:
- 不要提供任何修改对象的方法;
- 保证没有可被子类改写的方法;
- 使所有的域都是final的;
- 使所有的域都是private的;
- 保证对任何可变组件的互斥访问;
String就是一个典型的非可变类,这部分经常会出一些题目,有兴趣的可以看这个
https://blog.youkuaiyun.com/qq_42734874/article/details/81196721
复合优先于继承
继承和封装是矛盾的,继承打破了封装性,如果一个类可以被继承,那么它的子类会依赖超类中的一些实现细节,之后修改超类也会导致子类的实现发生变化,即使子类的代码没有发生变化。
但是复合可以避免这种问题的发生,它不再是扩展一个类,而是在新的类中增加一个私有域,引用了原来类的一个实例,原有类变成了新类的一个组成部分,新类可以调用原有类的方法而不会依赖于它的实现细节。
要么专门为继承而设计,并给出文档说明,要么禁止继承
继承涉及到构造方法和其他一系列方法的改写,它打破了封装性,出问题后分析起来也比较麻烦,如果不能明确知道继承的所有可能出现的问题,那么最好不要使用继承,如果专门为继承设计,那么必须在API中明确解释继承这些类的用法,可能出现的问题等等。
接口优于抽象类
Java只允许单继承,因此出现了接口的概念,接口使得安全增加一个类的功能成为可能,而如果继承于抽象类,则破坏了封装。
但接口也有不太好的一面,如果接口中的一个方法在它的所有实现类中都是一样的实现细节,那么这种实现就会变得很冗余,这时候也许可以将接口和抽象类的优点结合起来(称为骨架类),用抽象类实现那些公共方法,不同的方法由子类分别实现。
接口只是被用于定义类型
接口应该是用来定义类型的,而不应该用来导出变量。