4. 依赖倒置注意点
(1) 依赖正置
依赖正置 : 类之间的依赖是实体类之间的依赖, 即面向现实编程;
-- 例如 : 我开宝马车, 我 是 人类型, 宝马车 是车 类型, 依赖倒置就是 人 依赖 车, 依赖正置就是 我 依赖 宝马车;
(2) 依赖倒置使用场合
依赖倒置使用场景 :
-- 小项目 : 依赖倒置在小项目中得有点很难体现出来, 是否采用依赖倒置原则影响不大;
-- 大项目 : 项目越大, 需求改变越多, 采用依赖倒置原则设计的接口或抽象类 对 实现类的约束, 会大大减少维护成本;
(3) 依赖倒置与其它原则
依赖倒置与开闭原则联系 : 依赖倒置原则是实现开闭原则的重要途径, 依赖倒置原则没有实现, 无法对扩展开放, 对修改关闭;
四. 接口隔离原则
1. 接口隔离原则简介
(1) 接口分类
接口分类 :
-- 实例接口 : Java 中得一个类, 对一个类型的描述, 例如 Student xiaoming; 其中的 Student 类就是实例接口, 这不是我们这里所关心的;
-- 类接口 : Java 中得 Interface 接口, 这是我们所说的接口隔离原则中得接口;
(2) 接口隔离定义
接口隔离定义 : 建立单一的接口, 功能尽量细化, 不要建立臃肿的接口;
-- 不需要的接口 : 客户端尽量不依赖其不需要的接口, 客户端需要什么接口就提供什么接口, 剔除不需要的接口, 对接口进行细化, 保持接口方法最少;
-- 最小接口 : 类间的依赖关系应该建立在最小接口上, 细化接口;
(3) 接口隔离 与 单一职责区别
单一职责 与 接口隔离 区别 :
-- 单一职责 : 注重职责, 注重业务逻辑上得划分;
-- 接口隔离 : 注重的是接口的方法尽量少;
(4) 模块 与 接口
模块与接口 : 每个模块尽量都提供一个单一接口, 有几个模块, 就由几个接口, 避免建立一个庞大臃肿的接口对应所有的模块;
2. 接口隔离原则实现
(1) 接口尽量小
拆分接口 : 接口隔离的核心定义, 不出现臃肿的接口;
-- 限制 : 接口小有限度, 不能违反单一职责原则, 不要将一个业务逻辑拆分成两个接口;
-- 要求 : 根据接口隔离原则拆分接口时, 必须满足单一职责原则;
(2) 接口高内聚
高内聚 : 提高接口, 类, 模块的处理能力, 减少对外界交互;
-- 具体方法 : 接口中尽量少公布public 方法, 对外公布的 public 方法越少, 变更的风险就越小, 有利于后期的维护;
(3) 定制服务
定制服务 :
-- 起源 : 系统模块间的耦合需要有相互访问的接口, 这里就需要为各个 客户端 的访问提供定制的服务接口;
-- 要求 : 只提供访问者需要的方法, 不需要的就不提供;
(4) 接口隔离限度
接口隔离局限性 :
-- 粒度小 : 接口粒度越小, 系统越灵活, 但是同时使系统结构复杂, 开发难度增加, 降低了系统的可维护性;
-- 粒度大 : 灵活性降低, 无法提供定制服务, 增大项目风险;
3. 原子接口划分原则
原子接口或类 : 接口隔离原则 即适用于 接口的定义, 也适用于对类的定义, 那么这样的接口和类就是 原子接口 和 原子类;
(1) 接口模块一一对应
接口模块对应关系 : 一个接口只服务于一个子模块 或 业务逻辑;
(2) 压缩方法
方法压缩 : 通过业务逻辑, 压缩接口中得 public 方法, 减少接口的方法的数量;
(3) 接口修改
修改适配 : 尽量去修改已经污染的接口, 如果变更风险较大, 采用适配器模式进行转化处理;
五. 迪米特法则
1. 迪米特法则定义
迪米特法则 : 最少知识原则, 一个对象应该对其它对象有最少的了解, 即一个类对自己需要耦合或者调用的类知道的最少;
2. 低耦合要求
(1) 只和朋友交流
只与朋友通信 :
-- 朋友形成 : 一个对象与其它对象有耦合关系, 两个对象间的耦合使两个对象成为朋友关系;
-- 朋友定义 : 出现在 类 成员变量 , 方法参数返回值 中的类是朋友, 其它位置的不是朋友, 在方法体内出现的其它类不是朋友;
(2) 朋友距离
朋友间必须保持距离 :
-- 距离太近示例 : 朋友间不能无话不说, 无所不知, 类 A 与 B 耦合, B 将很多方法暴露给 A, 两个类之间的的耦合关系非常牢固, 这明显违反设计原则;
-- 保持距离方法 : 将 类 B 暴露给 A 的方法封装, 暴露的方法越少越好, 类 B 高内聚, 与 A 低耦合;
-- 设计方法 : 一个类的 public 方法越多, 修改时涉及的范围也就越大, 变更引起的风险也就越大, 在系统设计时要注意, 能用 private 就用private , 能用 protected 就用 protected, 能少用 public 就少用 public, 能加上 final 就加上 final;
(3) 类方法位置确定
原则 : 如果一个方法放在本类, 不增加类间关系, 不对类产生负面影响, 就放在本类中;
3. 迪米特法则注意事项
迪米特法则核心原则 : 类间解耦, 弱耦合, 耦合降低, 复用率提高;
-- 局限性 : 类间的耦合性太低, 会产生大量的中转或跳转类, 会导致系统的复杂性提高, 加大维护难度;
六. 开闭原则
1. 开闭原则定义
开闭原则定义 : 软件的实体 类, 模块, 函数 应该对扩展开放, 对修改关闭; 即 软件实体 应该 通过扩展实现变化, 不是通过 修改已有的代码实现变化;
-- 软件实体 : 软件产品中得 逻辑 划分模块, 抽象 和 类, 方法;
2. 变化
各种变化 :
-- 逻辑变化 : 变化一个逻辑模块, 其它模块不改变, 所有的依赖 或 关联关系都按照相同的逻辑处理;
-- 子模块变化 : 一个逻辑模块变化, 会影响其它模块, 低层次模块 (原子逻辑模块) 变化会引起高层次模块 (原子模块组合) 的变化, 通过扩展完成变化时, 高层次模块需要修改;
3. 开闭原则好处
开闭原则好处 :
-- 利于测试 : 如果改变软件内容, 需要将所有的测试流程都执行一遍, 如 单元测试, 功能测试, 集成测试等, 如果只是扩展, 只单独测试扩展部分即可;
-- 提高复用性 : 所有逻辑都从原子逻辑组合, 原子逻辑粒度越小, 复用性越大; 这样避免相同逻辑存在, 修改时需要修改多个此相同逻辑;
-- 提高可维护性 : 维护一个类最好的方式是 扩展一个类, 而不是修改一个类, 如果需要修改需要读懂源码才能修改, 扩展的话只需要了解即可, 直接继承扩展;