设计模式是什么
设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,使用设计模式是为了可重用代码、让代码更容易被他人理解并且保证代码可靠性。
狭义的设计模式是指GoF在《设计模式:可复用面向对象软件的基础》一书中所介绍的23种经典设计模式,不过设计模式并不仅仅只有这23种,随着软件开发技术的发展,越来越多的新模式不断诞生并得以应用。
设计模式一般包含模式名称、问题、目的、解决方案、效果等组成要素,其中关键要素是模式名称、问题、解决方案和效果。
- 模式名称(Pattern Name): 通过一两个词来描述模式的问题、解决方案和效果,以便更好地理解模式并方便开发人员之间的交流,绝大多数模式都是根据其功能或模式结构来命名的(GoF设计模式中没有一个模式用人名命名,);
- 问题(Problem): 描述了应该在何时使用模式,它包含了设计中存在的问题以及问题存在的原因;
- 解决方案(Solution): 描述了一个设计模式的组成成分,以及这些组成成分之间的相互关系,各自的职责和协作方式,通常解决方案通过UML类图和核心代码来进行描述;
- 效果(Consequences): 描述了模式的优缺点以及在使用模式时应权衡的问题。
GoF的23种设计模式各具特色,每个模式都为某一个可重复的设计问题提供了一套解决方案。根据它们的用途,设计模式可分为以下三种:
- 创建型模式(Creational): 主要用于描述如何创建对象,
- 结构型(Structural): 主要用于描述如何实现类或对象的组合,
- 行为型(Behavioral): 主要用于描述类或对象怎样交互以及怎样分配职责,
注:简单工厂模式不属于GoF 23种设计模式,但一般在介绍设计模式时都会对它进行说明,也许是太“简单”了,GoF并没有把它写到那本经典著作中,不过现在大部分的设计模式书籍都会对它进行专门的介绍。
设计模式基本原则
对于面向对象软件系统的设计而言,在支持可维护性的同时,提高系统的可复用性是一个至关重要的问题,如何同时提高一个软件系统的可维护性和可复用性是面向对象设计需要解决的核心问题之一。在面向对象设计中,可维护性的复用是以设计原则为基础的。每一个原则都蕴含一些面向对象设计的思想,可以从不同的角度提升一个软件结构的设计水平。
面向对象设计原则为支持可维护性复用而诞生,这些原则蕴含在很多设计模式中,它们是从许多设计方案中总结出的指导性原则。面向对象设计原则也是我们用于评价一个设计模式的使用效果的重要指标之一,在设计模式的学习中,大家经常会看到诸如“XXX模式符合XXX原则”、“XXX模式违反了XXX原则”这样的语句。
设计原则名称 | 定义 | 参考链接 | 使用频率 |
---|---|---|---|
单一职责原则(Single Responsibility Principle, SRP) | 一个类只负责一个功能领域中的相应职责 | 面向对象设计原则之单一职责原则 | ★★★★☆ |
开闭原则(Open-Closed Principle, OCP) | 软件实体应对扩展开放,而对修改关闭(即软件实体应尽量在不修改原有代码的情况下进行扩展。) | 面向对象设计原则之开闭原则 | ★★★★★ |
里氏代换原则(Liskov Substitution Principle, LSP) | 所有引用基类对象的地方能够透明地使用其子类的对象(继承必须确保超类所拥有的性质在子类中仍然成立) | 面向对象设计原则之里氏代换原则 | ★★★★★ |
依赖倒转原则(Dependence Inversion Principle, DIP) | 抽象不应该依赖于细节,细节应该依赖于抽象(要针对接口编程,而不是针对实现编程。开闭原则是目标,里氏代换原则是基础,依赖倒转原则是手段) | 面向对象设计原则之依赖倒转原则 | ★★★★★ |
接口隔离原则(Interface Segregation Principle, ISP) | 使用多个专门的接口,而不使用单一的总接口(客户端不应该依赖那些它不需要的接口。) | 面向对象设计原则之接口隔离原则 | ★★☆☆☆ |
合成复用原则(Composite Reuse Principle, CRP) | 尽量使用对象组合,而不是继承来达到复用的目的 | 面向对象设计原则之合成复用原则用 | ★★★★☆ |
迪米特法则(Law of Demeter, LoD) | 一个软件实体应当尽可能少地与其他实体发生相互作用(引入中间类,实体之间不再发生直接引用,而是将请求先转发给中间类,再由中间类来完成对其他实体的调用) | 面向对象设计原则之迪米特法则 | ★★★☆☆ |