一、设计模式的由来
设计模式从何而来
在介绍设计模式的起源之前,我们先要了解一下模式的诞生与发展。与很多软件工程技术一样,模式起源于建筑领域,毕竟与只有几十年历史的软件工程相比,已经拥有几千年沉淀的建筑工程有太多值得学习和借鉴的地方。
那么模式是如何诞生的?让我们先来认识一个人——Christopher Alexander(克里斯托弗.亚历山大)博士。Christopher Alexander博士及其研究团队用了约20年的时间,对住宅和周边环境进行了大量的调查研究和资料收集工作,发现人们对舒适住宅和城市环境存在一些共同的认同规律,Christopher Alexander在著作A Pattern Language: Towns, Buildings, Construction中把这些认同规律归纳为253个模式,对每一个模式(Pattern)都从Context(前提条件)、Theme或Problem(目标问题)、 Solution(解决方案)三个方面进行了描述,并给出了从用户需求分析到建筑环境结构设计直至经典实例的过程模型。
在Christopher Alexander的另一部经典著作《建筑的永恒之道》中,他给出了关于模式的定义:
每个模式都描述了一个在我们的环境中不断出现的问题,然后描述了该问题的解决方案的核心,通过这种方式,我们可以无数次地重用那些已有的成功的解决方案,无须再重复相同的工作。这个定义可以简单地用一句话表示:
模式是在特定环境下人们解决某类重复出现问题的一套成功或有效的解决方案。【A pattern is a successful or efficient solution to a recurring problem within a context】
软件工程中的设计模式
1990年,软件工程界开始关注ChristopherAlexander等在这一住宅、公共建筑与城市规划领域的重大突破。最早将模式的思想引入软件工程方法学的是1991-1992年以“四人组(Gang of Four,简称GoF,分别是Erich Gamma, Richard Helm, Ralph Johnson和John Vlissides)”自称的四位著名软件工程学者,他们在1994年归纳发表了23种在软件开发中使用频率较高的设计模式,旨在用模式来统一沟通面向对象方法在分析、设计和实现间的鸿沟。+
GoF将模式的概念引入软件工程领域,这标志着软件模式的诞生。软件模式(Software Patterns)是将模式的一般概念应用于软件开发领域,即软件开发的总体指导思路或参照样板。软件模式并非仅限于设计模式,还包括架构模式、分析模式和过程模式等,实际上,在软件开发生命周期的每一个阶段都存在着一些被认同的模式。
软件模式是在软件开发中某些可重现问题的一些有效解决方法,软件模式的基础结构主要由四部分构成,包括问题描述【待解决的问题是什么】、前提条件【在何种环境或约束条件下使用】、解法【如何解决】和效果【有哪些优缺点】
软件模式与具体的应用领域无关,也就是说无论你从事的是移动应用开发、桌面应用开发、Web应用开发还是嵌入式软件的开发,都可以使用软件模式。
在软件模式中,设计模式是研究最为深入的分支,设计模式用于在特定的条件下为一些重复出现的软件设计问题提供合理的、有效的解决方案,它融合了众多专家的设计经验,已经在成千上万的软件中得以应用。 1995年, GoF将收集和整理好的23种设计模式汇编成Design Patterns: Elements of Reusable Object-Oriented Software【《设计模式:可复用面向对象软件的基础》】一书,该书的出版也标志着设计模式正式成为面向对象(Object Oriented)软件工程的一个重要研究分支。
二、设计模式是什么(what)
设计模式的一般定义如下: 设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,使用设计模式是为了可重用代码、让代码更容易被他人理解并且保证代码可靠性。
狭义的设计模式是指GoF在《设计模式:可复用面向对象软件的基础》一书中所介绍的23种经典设计模式,不过设计模式并不仅仅只有这23种,随着软件开发技术的发展,越来越多的新模式不断诞生并得以应用。
设计模式一般包含模式名称、问题、目的、解决方案、效果等组成要素,其中关键要素是模式名称、问题、解决方案和效果。模式名称(Pattern Name)通过一两个词来描述模式的问题、解决方案和效果,以便更好地理解模式并方便开发人员之间的交流,绝大多数模式都是根据其功能或模式结构来命名的;问题(Problem)描述了应该在何时使用模式,它包含了设计中存在的问题以及问题存在的原因;解决方案(Solution)描述了一个设计模式的组成成分,以及这些组成成分之间的相互关系,各自的职责和协作方式,通常解决方案通过UML类图和核心代码来进行描述;效果(Consequences)描述了模式的优缺点以及在使用模式时应权衡的问题。
虽然GoF设计模式只有23个,但是它们各具特色,每个模式都为某一个可重复的设计问题提供了一套解决方案。根据它们的用途,设计模式可分为创建型(Creational),结构型(Structural)和行为型(Behavioral)三种,其中创建型模式主要用于描述如何创建对象,结构型模式主要用于描述如何实现类或对象的组合,行为型模式主要用于描述类或对象怎样交互以及怎样分配职责,在GoF 23种设计模式中包含5种创建型设计模式、7种结构型设计模式和11种行为型设计模式。此外,根据某个模式主要是用于处理类之间的关系还是对象之间的关系,设计模式还可以分为类模式和对象模式。我们经常将两种分类方式结合使用,如单例模式是对象创建型模式,模板方法模式是类行为型模式。+
值得一提的是,有一个设计模式虽然不属于GoF 23种设计模式,但一般在介绍设计模式时都会对它进行说明,它就是简单工厂模式,也许是太“简单”了,GoF并没有把它写到那本经典著作中,不过现在大部分的设计模式书籍都会对它进行专门的介绍。
常用设计模式一览表
类型 | 模式名称 | 学习难度 | 使用频率 |
---|---|---|---|
创建型模式 Creational Pattern | 单例模式 Singleton Pattern | ★☆☆☆☆ | ★★★★☆ |
创建型模式 | 简单工厂模式 Simple Factory Pattern | ★★☆☆☆ | ★★★★☆ |
创建型模式 | 工厂方法模式 Factory Method Pattern | ★★☆☆☆ | ★★★★★ |
创建型模式 | 抽象工厂模式 Abstract Factory Pattern | ★★★★☆ | ★★★★★ |
创建型模式 | 原型模式 Prototype Pattern | ★★★☆☆ | ★★★☆☆ |
创建型模式 | 建造者模式 Builder Pattern | ★★★★☆ | ★★☆☆☆ |
结构型模式 Structural Pattern | 适配器模式 Adapter Pattern | ★★☆☆☆ | ★★★★☆ |
结构型模式 | 桥接模式 Bridge Pattern | ★★★☆☆ | ★★★☆☆ |
结构型模式 | 组合模式 Composite Pattern | ★★★☆☆ | ★★★★☆ |
结构型模式 | 装饰模式 Decorator Pattern | ★★★☆☆ | ★★★☆☆ |
结构型模式 | 外观模式 Façade Pattern | ★☆☆☆☆ | ★★★★★ |
结构型模式 | 享元模式 Flyweight Pattern | ★★★★☆ | ★☆☆☆☆ |
结构型模式 | 代理模式 Proxy Pattern | ★★★☆☆ | ★★★★☆ |
行为型模式 Behavioral Pattern | 职责链模式 Chain of Responsibility Pattern | ★★★☆☆ | ★★☆☆☆ |
行为型模式 | 命令模式 Command Pattern | ★★★☆☆ | ★★★★☆ |
行为型模式 | 解释器模式 Interpreter Pattern | ★★★★★ | ★☆☆☆☆ |
行为型模式 | 迭代器模式 Iterator Pattern | ★★★☆☆ | ★★★★★ |
行为型模式 | 中介者模式 Mediator Pattern | ★★★☆☆ | ★★☆☆☆ |
行为型模式 | 备忘录模式 Memento Pattern | ★★☆☆☆ | ★★☆☆☆ |
行为型模式 | 观察者模式 Observer Pattern | ★★★☆☆ | ★★★★★ |
行为型模式 | 状态模式 State Pattern | ★★★☆☆ | ★★★☆☆ |
行为型模式 | 策略模式 Strategy Pattern | ★☆☆☆☆ | ★★★★☆ |
行为型模式 | 模板方法模式 Template Method Pattern | ★★☆☆☆ | ★★★☆☆ |
行为型模式 | 访问者模式 Visitor Pattern | ★★★★☆ | ★☆☆☆☆ |
三、为什么用设计模式(why)
(1) 设计模式来源众多专家的经验和智慧,它们是从许多优秀的软件系统中总结出的成功的、能够实现可维护性复用的设计方案,使用这些方案将可以让我们避免做一些重复性的工作,也许我们冥思苦想得到的一个“自以为很了不起”的设计方案其实就是某一个设计模式。在时间就是金钱的今天,设计模式无疑会为有助于我们提高开发和设计效率,但它不保证一定会提高,微笑。
(2) 设计模式提供了一套通用的设计词汇和一种通用的形式来方便开发人员之间沟通和交流,使得设计方案更加通俗易懂。交流通常很耗时,任何有助于提高交流效率的东西都可以为我们节省不少时间。无论你使用哪种编程语言,做什么类型的项目,甚至你处于一个国际化的开发团队,当面对同一个设计模式时,你和别人的理解并无二异,因为设计模式是跨语言、跨平台、跨应用、跨国界的。通俗,大家都懂!
(3) 大部分设计模式都兼顾了系统的可重用性和可扩展性,这使得我们可以更好地重用一些已有的设计方案、功能模块甚至一个完整的软件系统,避免我们经常做一些重复的设计、编写一些重复的代码。此外,随着软件规模的日益增大,软件寿命的日益变长,系统的可维护性和可扩展性也越来越重要,许多设计模式将有助于提高系统的灵活性和可扩展性,让我们在不修改或者少修改现有系统的基础上增加、删除或者替换功能模块。如果一点设计模式都不懂,我想要做到这一点恐怕还是很困难的。
(4) 最后一点对初学者很重要,学习设计模式将有助于初学者更加深入地理解面向对象思想,让你知道:如何将代码分散在几个不同的类中?为什么要有“接口”?何谓针对抽象编程?何时不应该使用继承?如果不修改源代码增加新功能?同时还让你能够更好地阅读和理解现有类库(如JDK)与其他系统中的源代码,让你早点脱离面向对象编程的“菜鸟期”。
(5)我觉得最重要的是,许多公司在面试的时候都会问,熟悉设计模式吗,了解设计模式吗,用过设计模式吗,如果你会不一定加分,如果你不会但一定会被减分的。
四、怎样学习设计模式(how)
1、看书,在互联网不发达的时候,这是获取知识最原始的途径。市面上关于设计模式的书真的很多,估计很多人都会挑花眼。
《大话设计模式》还成,里面的语言是C#,然而C#和Java很像
《设计模式之禅(第2版)》这本书我翻了一下,感觉还不错,用Java写的
《图解设计模式》,图解系列对新手是非常友好的,也是用Java写的,推荐
2、看博客、这个对于许多人来说都特别方便,一个电脑,一台手机知识随时随地学习,这个自己搜索吧。
3、看优秀开源软件的源代码,这个比较难,但对于对设计模式的理解是最快的,也是最深入的。Java的源码、dubbo源码、Spring 、SpringBoot等等
4、多写、就是多多练习写设计模式,当你能把一种设计模式写到非常熟悉的时候,你就对设计模式非常了解了。