15. 使类和成员的可访问性最小化(单一原则)

经验法则:让每个类或成员尽可能地不可访问

  • 有利于隐藏实现细节
  • 更利于开发、测试、优化、使用、理解和修改

    16. 在公共类中使用访问方法而不是公共属性

    使用getter和setter方法替代对外暴露成员属性;为未来修改内部表示提供了可能,但需要在getter、setter中加入业务逻辑的场景太少太少,类似lombok框架的设计使用可以看出,此类场景更多了为了满足面向对象的语法要求。当getter和setter已经成为“通用规范”时,强加逻辑反而会引起代码的混乱。

    17. 最小可变性

    不可变类相对可变类更加容易设计、实现和使用,不容易出错且更加安全
    设计不可变类原则:

  • 不要提供修改对象状态的方法

  • 确保这个类不能被继承
  • 把所有的属性都设置为final
  • 把所有的属性都设置为private
  • 确保对任何可变组件的互斥访问

    18. 组合优于集成

组合 继承
has-a关系 is-a关系
不破坏封装,整体和局部松耦合 破坏封装、子类依赖父类
支持拓展,随意增加组合累 只能继承一个父类,必须包含所有方法,增加系统复杂性

19. 要么设计继承并提供文档说明,要么禁用继承

如果一个类需要被继承,需要提供文档详细明确说明继承之后所带来的“副总用”,避免继承滥用所带来不必要的错误。

20. 接口优于抽象类

由于Java8默认方法的引入,为接口提供默认方法能力,补足相对于抽象类的唯一劣势,避免抽象类只能单继承的局限性。

21. 为后代设计接口

Java8默认方法为平滑的拓展类库设计提供了可能,同样的由于默认方法的出现使得客户端不必必须实现接口方法,默认方法的滥用可能导致必须实现的方法未被正确的重写。在设计接口时需仔细考虑

22. 接口仅用来定义类型

接口只能用于定义类型,不能用户导出常量

23. 类层次接口优于标签类

标签类冗长、易错、效率低下

24. 支持使用静态成员类而不是非静态类

如果成员类不需要防伪宿主实例,则需要把此成员类声明为static,因为每个非静态成员类实例都会有一个隐藏的外部引用指向宿主类,这会导致宿主类在满足垃圾回收的条件时无法被正常回收

25. 将源文件限制为单个顶级类