1. 好的设计原则
目录
- 一、应该具备的性质
- 二、面向对象设计原则
- 三、详解
- 3.1 开闭原则
- 3.2 单一职责原则
- 3.3 里氏替换原则
- 3.4 依赖倒置原则
- 3.5 接口隔离原则
- 3.6 合成复用原则
- 3.7 迪米特原则
一、应该具备的性质
- 可扩展性
- 灵活性
- 可插入性
二、面向对象设计原则
以下设计原则的重要性从高到低排列
名称 | 简介 | 重要度 |
---|---|---|
开闭原则 | 软件实体对扩展是开放的,但对修改是关闭的,即在不修改一个软件实体的基础上去扩展其功能 | 💪💪💪💪💪 |
依赖倒置原则 | 要针对抽象层编程,而不要针对具体类编程 | 💪💪💪💪💪 |
单一职责原则 | 类的职责要单一、不能将太多的职责放在一个类中 | 💪💪💪💪 |
里氏替换原则 | 在软件系统中,一个可以接受基类对象的地方必然可以接受一个子类对象 | 💪💪💪💪 |
合成复用原则 | 在系统中应该尽量多使用组合和聚合关联关系,尽量少用甚至不用继承关系 | 💪💪💪💪 |
迪米特法则 | 一个软件实体对其他实体的引用越少越好,或者说如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用,而是通过引入一个第三者发生间接交互 | 💪💪💪 |
接口隔离原则 | 使用多个专门的接口来取代一个统一的接口 | 💪💪 |
三、详解
3.1 开闭原则
- 抽象化是开闭原则的关键。
- 要求开发人员可以在不修改系统中现有功能代码的前提下,实现对应用系统的软件功能进行扩展。
3.2 单一职责原则
- 高内聚性原则
- 避免相同的职责(功能)分散到不同的类中实现
- 避免一个类承担过多的职责
- 可以减少类之间的耦合
- 数据库类设计示例
- 数据库连接和数据库访问操作相互分离
- 例如数据库连接分为Mysql和Orcal连接
- 相应的访问也会有Mysql和Orcal访问
3.3 里氏替换原则
- 凡是父类出现的地方,都可以用子类进行替代
- 里氏替换原则
- 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法
- 子类中可以增加自己特有的方法
- 当子类的方法重载父类的方法时,方法的形参要比父类方法的输入参数更宽松
- 当子类的方法实现父类的抽象方法时,方法的返回值要比父类更严格。
3.4 依赖倒置原则
- 将依赖关系倒置为依赖接口
- 上层模块不应该依赖于下层模块,它们共同依赖于一个抽象
- 父类不能依赖子类,它们都要依赖抽象类
- 抽象不能依赖于具体,具体应该依赖于抽象
- 示例如下
- 左图显示了类之间的严格依赖,耦合性非常强
- 应该做如下修改
- 找到类之间共同的行为约束(接口)
- 客户端程序不针对具体的类进行调用,而是调用接口
- 这样就屏蔽了类之间的强关联关系
3.5 接口隔离原则
- 一个类对另外一个类的依赖性应当是建立在最小的接口上
- 客户端不应该依赖那些它不需要的接口(方法)
- 仍然需要考虑接口的单一职责原则
- 如何避免不良好的接口设计
- 用多个专门的接口,而不使用单一的总接口
- 一个接口就只代表一个角色
- 使用接口隔离原则拆分接口时,首先必须满足单一职责原则
3.6 合成复用原则
- 也称为组合/聚合复用原则
- 尽量使用对象组合,而不是继承来达到复用目的
- 一个新的对象里通过关联关系(包括组合关系和聚合关系)来使用一些已有的对象
- 新对象通过委派调用已有对象的方法达到复用其已有功能的目的
- 简单来说,就是要尽量使用组合/聚合关系,少用继承!
- 继承复用: 实现简单,易于扩展,没有足够的“灵活性”(“白箱”复用)
- 上面的类
StudentDAO
拥有了DBUtil
类的行为以及属性 - 那么两个类之间具有了强耦合关系,尤其是
DBUtil
父类发生改变时,其子类StudentDAO
和TeacherDAO
都会受到影响。 - 组合/聚合复用:耦合度相对较低,选择性地调用成员对象的操作;可以在运行时动态进行(“黑箱”复用)
- 让类
StudentDAO
拥有了DBUtil
类的实例 - 此时
StudentDAO
类依然拥有了DBUtil
类的属性和行为 - 如此以来耦合性就会降低
- 如果想近一步降低耦合性,则将
DBUtil
类设计为接口,在其它地方实现即可。
- 让类
3.7 迪米特原则
- 要求一个软件实体应当
尽可能少
的与其他实体发生相互作用 - 又称为最少知识原则
- 不要和“陌生人”说话
- 只与你的直接朋友通信
- 每一个软件单位对其他的单位都只有最少的知识,而且局限于那些本单位密切相关的软件单位
- 简单来说就是,创建松耦合的类
- 某系统界面类(如Form1、Form2等类)与数据访问类(如DAO1、DAO2等类)之间的调用关系较为复杂,如图所示
- 如果其中的一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用