在软件工程中,设计模式(Design Patterns)是对软件设计中普遍存在、反复出现的各类问题所提出的解决方案。这个术语是由埃里希·伽玛(Erich Gamma)等人在 1990 年从建筑设计领域引入到计算机科学之中。
设计模式(Design pattern)代表了软件工程中的最佳实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。
设计模式并不直接用来完成代码的编写,而是描述在各种不同情况下,要怎么解决问题的一种方案。面向对象设计模式通常以类别或对象来描述其中的关系和相互作用,但不涉及用来完成应用程序的特定类别或对象。设计模式能使不稳定依赖于相对稳定、具体依赖于相对抽象,避免会引起麻烦的紧耦合,以增强软件设计面对并适应变化的能力。
并非所有的软件模式都是设计模式,设计模式特指软件“设计”层次上的问题。还有其他非设计模式的模式,如架构模式。同时,算法不能算是一种设计模式,因为算法主要是用来解决计算上的问题,而非设计上的问题。
《设计模式:可复用面向对象软件的基础》(Design Patterns: Elements of Reusable Object-Oriented Software)是软件工程领域有关软件设计的一本书,提出和总结了对于一些常见软件设计问题的标准解决方案,称为软件设计模式。该书作者是 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides,后以“四人帮”(Gang of Four,GoF)著称,书中的设计模式也被成为“四人帮设计模式”(Gang of Four design patterns)。
大部分设计模式都有正规的描述方式,以便在不同情况下使用。
设计模式的描述通常会包含以下部分:
- 意图:简单描述问题和解决方案。
- 动机:进一步解释问题并说明设计模式如何提供解决方案。
- 结构:展示设计模式的每个部分和它们之间的关系。
- 实现:提供设计模式主流程序设计语言的代码实现,帮助程序员更好地理解设计模式背后的思想。
另外,部分设计模式还会列出其他的一些实用细节,例如:该设计模式的适用性、实现步骤以及与其他设计模式的关系等。
《设计模式》一书把设计模式分为创建型模式、结构型模式、行为型模式,把它们通过授权、聚合、诊断的概念来描述。
创建型模式用于对象的创建,是对类构造函数直接构造的补充与完善。创建型模式使得对象的创建过程更加动态化与定制化,使得对象创建具备更高的灵活性,程序员可以灵活控制哪些对象应该被创建,如何被创建,如何初始化等等。
名称 | 描述 |
---|---|
单例模式(Singleton) | 确保一个类只有一个类对象实例,并提供对该实例的全局访问。 |
工厂模式(Factory) | 用于复杂对象的创建,将类对象的初始化过程交由工厂类完成。 |
抽象工厂模式(Abstract Factory) | 对工厂模式更深层次的抽象,由抽象工厂创建具体的工厂类。 |
建造者模式(Builder) | 将复杂对象的构建过程进行抽象(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象。 |
原型模式(Prototype) | 通过复制一个已经存在的对象实例来返回新的对象实例,而不是新建实例,多用于复杂对象或者耗时实例的创建。 |
表:创建型模式
结构型模式指导程序员如何将系统的各个不同部分有机地、灵活地组织起来,形成功能完备、可靠性强的完整程序。
名称 | 描述 |
---|---|
适配器模式(Adapter) | 将某个类的接口转换成另一接口表示,消除由于接口不匹配所造成的兼容性问题。 |
桥接模式(Bridge) | 将事物对象和其具体行为、具体特征分离开来,使它们可以各自独立的变化。 |
组合模式(Composite) | 将对象组合成树形结构以表示"部分-整体"的层次结构,使得对单个对象和组合对象的使用具有一致性。 |
装饰器模式(Decorator) | 向一个现有的对象添加更多新的功能,同时又不改变其结构。 |
外观模式(Facade) | 为子系统中的一组接口提供一个一致的外观界面,以隐藏系统的复杂性。 |
享元模式(Flyweight) | 通过共享方式重用对象,主要用于减少创建对象的数量,减少内存占用和提高程序性能。 |
代理模式(Proxy) | 为对象提供一个代理以控制对这个对象的访问。 |
表:结构型模式
行为型模式是程序员对类或对象实例的行为操作进行的抽象。
名称 | 描述 |
---|---|
职责链模式(Chain of Responsibility) | 为请求创建一个接收者对象的链,对请求的发送者和接收者进行解耦。 |
命令模式(Command) | 将请求封装为对象,传递给调用对象,使得不同的请求可以参数化。 |
解释器模式(Interpreter) | 给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。 |
迭代器模式(Iterator) | 提供一种方法顺序访问集合对象中的各个元素, 而又不需暴露该对象的内部实现。 |
中介者模式(Mediator) | 通过中介对象来封装一系列的对象交互,使得交互对象之间耦合松散,降低多个对象和类之间的通信复杂性。 |
备忘录模式(Memento) | 保存一个对象的某个状态,从而可以在将来合适的时候把这个对象还原到目标状态。 |
观察者模式(Observer) | 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被更新。 |
状态模式(State) | 为类定义多种状态模式,对象实例在内部状态发生改变时其行为也发生改变。 |
策略模式(Strategy) | 一个类的行为或算法可以在运行时相互替换更改。 |
模板方法模式(Template Method) | 先构建一个顶级逻辑框架,而将逻辑的细节留给具体的子类去实现,使得子类可以不改变顶层逻辑结构的情况下即可重定义某些特定步骤。 |
访问者模式(Visitor) | 封装一些施加于某种数据结构元素之上的操作,一旦这些操作需要修改,接受这个操作的数据结构可以保持不变。 |
表:行为型模式