设计原则

设计原则

  1. 关闭原则: 对拓展开放, 对修改关闭
    image1

  2. 里氏代换原则: 基类出现的地方,子类一定能出现.
    (如果你有一段使用父类的代码,换成子类对象后,功能和逻辑应该保持一致)

子类可以拓展父类的功能,但是不能改变父类原有的功能
子类要保持父类行为的一致性

  • 输入输出、异常、状态变化最好符合父类约定
    不要随意重写父类方法
  • 如果子类行为与父类完全不同,最好不要继承
  • 可以考虑 组合(has-a)代替继承(is-a)

总结:

  • LSP 是为了 保证继承层次的可替换性
  • 重写父类方法可能破坏这一点,导致父类代码假设失效
  • 如果子类不能合理实现父类行为,继承可能不是最好的设计

比如鸡和鸟,鸡不会飞, 不太适合继承鸟—->将飞写成接口
比如矩形和正方形, 矩形能设置不同长宽的方法, 但是正方形只能设置相同的边长
–>将getlength,getwidth写成接口

  1. 依赖倒转原则 :高层模块不应该依赖低层模块,二者都应该依赖抽象(接口或抽象类)。
    抽象不应该依赖细节,细节应该依赖抽象。

你写业务逻辑(高层模块)的时候,不要直接去 new 一个具体实现(低层模块),而是依赖接口。

DIP = 设计原则 → “依赖接口而不是实现”

  1. 接口隔离原则: 客户端不能被迫依赖于他不使用的方法, 一个类
    不要让一个类依赖它不需要的接口。
    一个大的接口应该拆分成多个更小、更专一的接口。

  2. 迪米特原则(最少知道原则):“不要和陌生人说话。”
    对象之间的“通信”应该尽量松散:

  • 一个类只与直接关联的类(成员变量、方法参数、返回值)打交道;
  • 不应该通过一层又一层的“传话”去访问别的对象。
    明星 通过经纪人 商业洽谈/粉丝见面
    要做软件的公司 通过软件公司 找软件工程师做软件
  1. 合成复用原则:尽量用组合/聚合,避免使用继承/实现, 来完成代码复用
  • 继承会带来强耦合:父类改动可能影响所有子类;
  • 组合/聚合关系更灵活:可以在运行时动态替换组件;
  • 面向接口编程 + 依赖倒转原则,可以让“组合”更优雅地实现。