设计模式概述 原创 设计模式 2021年10月11日 06:51 夏至未至 1126 当前内容 3507 字,在路上,马上到,马上到 ### 目录 [TOC] ### 设计模式定义 设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,使用设计模式是为了可重用代码、让代码更容易被他人理解并且保证代码可靠性。 ### 设计模式作用 1. 设计模式是从众多优秀的软件系统中总结出的成功的、能够实现可维护性复用的设计方案,使用这些方案将避免一些重复性工作,高效设计出高质量的软件系统。 2. 设计模式提供了一套通用的设计词汇和一种通用的形式来方便开发人员之间沟通和交流,使得设计方案更加通俗易懂。 3. 大部分设计模式都兼顾了系统的可重用性和可扩展性,这使得我们可以更好地重用一些已有的设计方案、功能模块甚至一个完整的软件系统,避免我们经常做一些重复的设计、编写一些重复的代码。 ### 设计模式原则 一般遵循如下七项基本原则,另外特殊情况,特殊对待: 1. 单一职责原则 (Single Responsibility Principle) 2. 开放-关闭原则 (Open-Closed Principle) 3. 里氏替换原则 (Liskov Substitution Principle) 4. 依赖倒转原则 (Dependence Inversion Principle) 5. 接口隔离原则 (Interface Segregation Principle) 6. 迪米特法则(Law Of Demeter) 7. 组合/聚合复用原则 (Composite/Aggregate Reuse Principle) #### 单一职责 ##### 理解 从软件的角度来说,一个类,应该仅有一个让它变化的原因,即一个类只负责一项职责。假设某个类 A 负责两个不同的职责,职责 A1 和 职责 A2,那么当职责 A1 需求发生改变而需要修改类 A,有可能会导致原来运行正常的职责 A2 功能发生故障 ##### 总结 单一职责原则,是一个简单又直观的原则,但是在实际编码的过程中很难将它恰当地运用,需要结合实际情况进行运用(具体情况,具体对待)。 单一职责原则,可以降低类的复杂度,一个类仅负责一项职责,其逻辑肯定要比负责多项职责简单。 单一职责原则,提高了代码的可读性,提高系统的可维护性 #### 开放-封闭原则 ##### 理解 开放-封闭原则表示软件实体 (类、模块、函数等等) 应该是可以被扩展的,但是不可被修改 ##### 总结 可以具有良好的可扩展性,可维护性。 不过,不可能让一个系统的所有模块都满足 开放-封闭 原则,我们能做到的是尽可能地不要修改已经写好的代码,已有的功能,而是去扩展它。 如果一个软件能够满足 开放-封闭 原则,那么它将有两项优点: 1. 能够扩展已存在的系统,能够提供新的功能满足新的需求,因此该软件有着很强的适应性和灵活性。 2. 已存在的模块,特别是那些重要的抽象模块,不需要被修改,那么该软件就有很强的稳定性和持久性。 #### 里氏替换原则 ##### 理解 当使用继承时候,子类继承父类时,除添加新的方法完成新增功能,尽量不要修改父类方法预期的行为。 里氏替换原则的重点在不影响原功能,而不是不覆盖原方法。 继承包含这样一层含义:父类中凡是已经实现好的方法(相对于抽象方法而言),实际上是在设定一系列的规范和契约,虽然它不强制要求所有的子类必须遵从这些契约,但是如果子类对这些非抽象方法任意修改,就会对整个继承体系造成破坏。而里氏替换原则就是表达了这一层含义。 ##### 总结 里氏替换原则通俗的来讲就是:子类可以扩展父类的功能,但不能改变父类原有的功能。 #### 依赖倒转原则 ##### 理解 高层模块不应该依赖低层模块,二者都应该依赖于抽象。就是说,抽象不应该依赖于细节,细节应该依赖于抽象。 举个例子, 某天产品经理需要添加新的功能,该功能需要操作数据库,一般负责封装数据库操作的和处理业务逻辑分别由不同的程序员编写。 封装数据库操作可认为低层模块,而处理业务逻辑可认为高层模块,那么如果处理业务逻辑需要等到封装数据库操作的代码写完的话才能添加的话讲会严重拖垮项目的进度。 正确的做法应该是处理业务逻辑的程序员提供一个封装好数据库操作的抽象接口,交给低层模块的程序员去编写,这样双方可以单独编写而互不影响。 ##### 总结 依赖倒转原则的核心就是要我们面向接口编程,理解了面向接口编程,也就理解了依赖倒转。 #### 接口隔离原则 接口隔离原则,其 "隔离" 并不是准确的翻译,真正的意图是 “分离” 接口(的功能) 接口隔离原则强调:客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。 ##### 总结 接口隔离原则的思想在于建立单一接口,尽可能地去细化接口,接口中的方法尽可能少 但是凡事都要有个度,如果接口设计过小,则会造成接口数量过多,使设计复杂化。所以一定要适度。 #### 迪米特法则(最少知道原则) ##### 理解 它表示一个对象应该对其它对象保持最少的了解。通俗来说就是,只与直接的朋友通信。 什么是直接的朋友:每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系,我们就说这两个对象之间是朋友关系。耦合的方式很多,依赖、关联、组合、聚合等。其中,我们称出现成员变量、方法参数、方法返回值中的类为直接的朋友,而出现在局部变量中的类则不是直接的朋友。也就是说,陌生的类最好不要作为局部变量的形式出现在类的内部。 #### 总结 对于被依赖的类来说,无论逻辑多么复杂,都尽量的将逻辑封装在类的内部,对外提供 public 方法,不对泄漏任何信息。 #### 组合聚合复用原则 ##### 理解 组合/聚合复用原则就是在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分; 新的对象通过向这些对象的委派达到复用已有功能的目的。 在面向对象的设计中,如果直接继承基类,会破坏封装,因为继承将基类的实现细节暴露给子类;如果基类的实现发生了改变,则子类的实现也不得不改变;从基类继承而来的实现是静态的,不可能在运行时发生改变,没有足够的灵活性。于是就提出了组合/聚合复用原则,也就是在实际开发设计中,尽量使用组合/聚合,不要使用类继承。 ##### 总结 总体说来,组合/聚合复用原则告诉我们:组合或者聚合好过于继承。 聚合组合是一种 “黑箱” 复用,因为细节对象的内容对客户端来说是不可见的。 ### 设计模式分类 #### 创建型模式 创建型模式主要用于描述如何创建对象 1. [单例模式](https://www.codecomeon.com/posts/42/ "单例模式") 2. [工厂方法模式](https://www.codecomeon.com/posts/61/ "工厂方法模式") 3. [抽象工厂模式](https://www.codecomeon.com/posts/62/ "抽象工厂模式") 4. [原型模式](https://www.codecomeon.com/posts/63/ "原型模式") 5. [建造者模式](https://www.codecomeon.com/posts/64/ "建造者模式") #### 结构型模式 结构型模式主要用于描述如何实现类或对象的组合 1. [适配器模式](https://www.codecomeon.com/posts/65/ "适配器模式") 2. [桥接模式](https://www.codecomeon.com/posts/66/ "桥接模式") 3. [组合模式](https://www.codecomeon.com/posts/67/ "组合模式") 4. 装饰模式 5. 外观模式 6. 享元模式 7. 代理模式 #### 行为型模式 行为型模式主要用于描述类或对象怎样交互以及怎样分配职责 1. 职责链模式 2. 命令模式 3. 解释器模式 4. 迭代器模式 5. 中介者模式 6. 备忘录模式 7. 观察者模式 8. 状态模式 9. 策略模式 10. 模板方法模式 11. 访问者模式 本文标题: 设计模式概述 本文作者: 夏至未至 发布时间: 2021年10月11日 06:51 最近更新: 2022年9月4日 12:37 原文链接: 许可协议: 署名-非商业性-禁止演绎 4.0 国际(CC BY-NC-ND 4.0) 请按协议转载并保留原文链接及作者 设计模式(25) 上一个 C++设计模式-单例模式 下一个 C/C++学习书籍资料整理 当前文章评论暂未开放,请移步至留言处留言。