设计模式(一)——认识设计模式
前言
一直想写设计模式系列的博客,但是一直下不了决心去写。一方面是自己刚开始工作,有时候腾不出那么多时间学习,另一方面是因为看了网上好多设计模式的文章,感觉他们总结的都很到位,自己再写也写不太好。但最后还是决定写一下,因为知识只有自己梳理一遍才记得牢固,不管写的好不好都是自己的。
这个系列我打算以初学者的身份一点一点去挖掘每一个设计模式,用宇明大佬教的《费曼学习法》用讲解的语气去写每一篇文章。ok,言归正传,我们开始今天的文章——设计模式(一)设计模式概述
在看到标题的时候,我想作为一个初学者应该会先提出这些问题:
- 什么是模式?什么是设计模式?
- 我们为什么要学习设计模式?设计模式对我们开发有什么帮助?
- 我们如何学习设计模式?
接下来我们就带着这些问题来学习今天的内容。
一、什么是模式?什么又是设计模式?
什么是模式?我们先从字面意思来理解,“模”模型、模具,我们可以看做是一种标准,“式”形式、方式,我们可以看做是一种方法,两者组合在一起就是“标准化的方法”叫做模式。
举个很恰当了例子:中国的四大发明之一,活字印刷术的诞生过程就是一种模式的产生。在没有活字印刷术之前,每页文字刻成一个板子,如果一个字错了就得重新雕刻,错误率很高,成本也高,效率还低。之后演变成为每个字为单独小板,印刷文章的时候只需要在大板子上根据需求排列不同的字就可以了,这些字不仅雕刻起来错误率低,还可以重复不同的文章使用。这是一种标准化方法的演变过程,也是一种模式的诞生。
每个模式都描述了一个在我们的环境中不断出现的问题,然后描述了该问题的解决方案的核心,通过这种方式,我们可以无数次地重用那些已有的成功的解决方案,无须再重复相同的工作。简而言之就是:模式是在特定环境下人们解决某类重复出现问题的一套成功或有效的解决方案。
上面我们了解了模式,但有的朋友该说了,我们是软件开发工作者,知道模式有什么用呢?别着急,下面我们就来认识一下软件模式。
软件模式,如果按刚才我们理解的“模式”,软件模式就可以解读为:软件生命周期内的一些标准化方法。我们知道软件的生命周期并不单单只开发周期,软件前期的需求分析,后期的迭代维护都属于软件的生命周期,所以相对应的在每个阶段都会有对应的模式。作为开发者我们接触最多的就是开发阶段,而在开发阶段使用最多的应该就是设计模式了。那什么又是设计模式呢?
据网上搜索得知:设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,使用设计模式是为了可重用代码、让代码更容易被他人理解并且保证代码可靠性。其实说白了,设计模式就是经过无数填坑人的努力所总结的一套标准化的被所有开发者承认的代码设计方案。
设计模式一般包含模式名称、问题、目的、解决方案、效果等组成要素,其中关键要素是模式名称、问题、解决方案和效果。
模式名称(Pattern Name)通过一两个词来描述模式的问题、解决方案和效果,以便更好地理解模式并方便开发人员之间的交流,绝大多数模式都是根据其功能或模式结构来命名的;
问题(Problem)描述了应该在何时使用模式,它包含了设计中存在的问题以及问题存在的原因;
解决方案(Solution)描述了一个设计模式的组成成分,以及这些组成成分之间的相互关系,各自的职责和协作方式,通常解决方案通过UML类图和核心代码来进行描述;
效果(Consequences)描述了模式的优缺点以及在使用模式时应权衡的问题。
个人感觉这些已经很全面的解释了什么是设计模式,之后我也打算从这四个方面去分析每一种模式。
二、设计模式是为了解决什么样的问题?我们为什么要学习设计模式?
认识完设计模式我们肯定会产生以下疑问?我们为什么要学习设计模式?它在我们开发当中都解决了哪些问题?
通过学习我觉得学习设计模式可以解决以下三个问题:
1、避免重复造轮子
学习计算机我们肯定都听过这句话“不要重复造轮子”,设计模式首先解决的就是我们重复造轮子的问题。
举个栗子:在没有学习设计模式的时候,我们使用图片加载或者其他工具类,肯定是经过大量的编程,走过很多弯路,填过很多坑才会想到“我们应该封装一下,单独一个实例这样更加便于管理”,于是我们开始封装,废了好大劲封装成功,之后学习完 “单例模式”发现,咦,这不就是我封装的那个方式么?如果早学了设计模式,我就。。。。所以,在时间就是金钱的今天,设计模式无疑会为有助于我们提高开发和设计效率,但它不保证一定会提高。
2、降低沟通成本
工作中我们不可能是一直独立开发,肯定会跟别人协调开发。只要有合作就少不了沟通,设计模式也能解决开发人员之间的沟通问题。
再举个栗子:你从零开发了一个项目,后来项目越做越大,功能模块也越来越多,多到你天天加班也弄不完的情况,这个时候你向老板提出“涨工资不然不干了,然后老板开始给你各种画饼。。。”(扯远了),这时候你向老板提出需要一个帮手,然后老板给你招来一个小弟,你需要带他熟悉项目,你对他说我这个地方用了“单例模式”,这里用了“装饰者模式”,然后这里是“工厂模式”,然后小弟懵逼了。然后你还得费好大劲去讲解你是怎么实现的这些模式。。。很显然小弟并不了解设计模式,不然你就可以省下很多时间多写几个bug了。
因为设计模式提供了一套通用的设计词汇和一种通用的形式来方便开发人员之间沟通和交流,使得设计方案更加通俗易懂,所以无论你使用哪种编程语言,做什么类型的项目,甚至你处于一个国际化的开发团队,当面对同一个设计模式时,你和别人的理解并无二异,因为设计模式是跨语言、跨平台、跨应用、跨国界的。
3、优秀的复用性和可扩展性
上大学的时候我们学过,一个优秀的软件需要有六大特性:功能性、可靠性、可用性、效率、可维护性、可移植性。然而很多开发人员在开发的时候多半不会考虑这些东西。因为国内的开发环境大多是先出结果,出问题了再说。
所以,如何在有限的时间内开发出优秀的软件是成为优秀开发人员的必修之路。大部分设计模式都兼顾了系统的可重用性和可扩展性。例如:代码中经常使用某个功能,我们可以使用“单例模式”把他封装起来,如果考虑某个地方的可扩展性,我们可以使用“装饰模式”等等。
三、常用的设计模式都有哪些?
经过无数前辈的总结,常用的设计模式主要有23种,而这23种设计模式又可以分为三大类:创建型模式(5种)、结构型模式(7种)和行为型模式(11种)。
其中创建型模式主要用于描述如何创建对象,结构型模式主要用于描述如何实现类或对象的组合,行为型模式主要用于描述类或对象怎样交互以及怎样分配职责。下图是23种模式的具体分类:
创建型模式 Creational Pattern |
---|
单例模式 Singleton |
原型模式 Prototype 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 |
注:之后每学习一个模式,我们会在表格后面增加模式的概述,使用场景等内容
四、我们如何学习设计模式?
我从大学开始接触设计模式,虽然是门选修课,但它是我唯一 一门没有逃过一节课的选修课。毕业后我也从事了近两年的开发工作。在这期间我体会到了设计模式的种种便利,也了解一些朋友对设计模式的看法。在这里我想分享一下自己学习设计模式的心得体会,供大家参考:
1、不要畏惧。工作期间我跟很多同事谈论过设计模式,他们大多数的反应是“那个感觉挺难的,现在没打算去学。”很多人还没开始就已经退缩了。其实掌握设计模式并不是很难的事情,我们只需要拆分他们,一个一个模式去熟悉,一个例子一个例子去看、去模仿,多思考,多实践,一定可以掌握。关键是要开始去学。
2、抓住重点。其实学习每一个设计模式只需要抓住以下几点,我们就能大概掌握这种模式。
- 这个设计模式是要解决什么问题,需要在那种情况下使用?
- 这个设计模式的结构图是什么样的?
- 这个设计模式的优缺点分别是什么?
- 在现实和代码中分别能举出什么样的使用该模式的例子?
3、亲身实践。老话说:“纸上得来终觉浅,绝知此事要躬行”,看十遍例子也不如敲一遍代码,一定要把例子敲一遍,并且举一反三自己设计例子。这样才能记得牢固。
4、不能滥用。千万不要滥用模式,不要刚学了一两个模式就想在代码中硬套。每个模式都有自己的适用场景,不能为了使用模式而使用模式。要做到具体情况具体分析,滥用设计模式很可能写出一堆垃圾代码。
5、活学活用。我这里直接用刘伟老师的总结来解释。
设计模式的“上乘”境界:“手中无模式,心中有模式”。模式使用的最高境界是你已经不知道具体某个设计模式的定义和结构了,但你会灵活自如地选择一种设计方案【其实就是某个设计模式】来解决某个问题,设计模式已经成为你开发技能的一部分,能够手到擒来,“内功”与“招式”已浑然一体,要达到这个境界并不是看完某本书或者开发一两个项目就能够实现的,它需要不断沉淀与积累,所以,对模式的学习不要急于求成,要循序渐进。
五、结语
最后用软件工程大师之一John Vlissides的著作《设计模式沉思录》(Pattern Hatching Design Patterns Applied)中的一句话来结束这篇文章:
模式从不保证任何东西,它不能保证你一定能够做出可复用的软件,提高你的生产率,更不能保证世界和平。模式并不能替代人来完成软件系统的创造,它们只不过会给那些缺乏经验但却具备才能和创造力的人带来希望。
本文参考:
《设计模式——可复用面向对象软件的基础》
《Head First设计模式》
《大话设计模式》
【刘伟 http://blog.csdn.net/lovelion】