设计模式精解-GoF 23种设计模式解析.pdf
《设计模式精解-GoF 23种设计模式解析.pdf》由会员分享,可在线阅读,更多相关《设计模式精解-GoF 23种设计模式解析.pdf(105页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、设计模式精解GoF 23 种设计模式解析附 C+实现源码 http:/ 设计模式精解设计模式精解GoF 23 种设计模式解析附种设计模式解析附 C+实现源码实现源码 目目 录录 0 引言.2 0.1 设计模式解析(总序).2 0.2 设计模式解析后记.2 0.3 与作者联系.5 1 创建型模式.5 1.1 Factory模式.5 1.2 AbstactFactory模式.11 1.3 Singleton模式.16 1.4 Builder模式.18 1.5 Prototype模式.23 2 结构型模式.26 2.1 Bridge模式.26 2.2 Adapter模式.31 2.3 Decorat
2、or模式.35 2.4 Composite模式.40 2.5 Flyweight模式.44 2.6 Facade模式.49 2.7 Proxy模式.52 3 行为模式.55 3.1 Template模式.55 3.2 Strategy模式.59 3.3 State模式.63 3.4 Observer模式.68 3.5 Memento模式.73 3.6 Mediator模式.76 3.7 Command模式.81 3.8 Visitor模式.87 3.9 Chain of Responsibility模式.92 3.10 Iterator模式.96 3.11 Interpreter模式.100
3、4 说明.105 第 1 页 共 105 页 k_eckel 设计模式精解GoF 23 种设计模式解析附 C+实现源码 http:/ 0 引言引言 0.1 设计模式解析(总序)设计模式解析(总序)“Next to My Life,Software Is My Passion”Robert C.Martin.懂了设计模式,你就懂了面向对象分析和设计(OOA/D)的精要。反之好像也可能成立。道可道,非常道。道不远人,设计模式亦然如此。一直想把自己的学习经验以及在项目中的应用经历拿出来和大家共享,却总是下不了这个决心:GoF 的 23 种模式研读、总结也总需要些时日,然而时间对于我来说总是不可预计的
4、。之所以下了这个决心,有两个原因:一是 Robert 的箴言,二是因为我是一个感恩的人,就像常说的:长怀感恩之心,人生便无遗憾。想想当时读 GoF 的那本圣经时候的苦闷、实现 23 个模式时候的探索、悟道后的欣悦,我觉得还是有这个意义。0.2 设计模式解析后记设计模式解析后记 写完了Interpreter模式之后,我习惯性的看看下一天的安排,却陡然发现GoF的 23个设计模式的解析已经在我不经意间写完了。就像在一年前看GoF的设计模式一书,和半年前用C+模拟、实现 23 种经典的设计模式一般,透过这个写解析的过程,我又看到了另外一个境界。一直认为学习的过程很多时候可以这样划分:自己学会一门知识
5、(技术)、表达出来、教会别人、记录下来,虽然这个排序未必对每个人都合适(因为可能不同人有着不同的特点能力)。学一门知识,经过努力、加以时日,总是可以达到的,把自己学的用自己的话表达出来就必须要将学到的知识加以消化、理解,而教会一个不懂这门知识的人则比表达出来要难,因为别人可能并不是适应你的表述方式,记录下来则需要经过沉淀、积累、思考,最后厚积薄发,方可小成。设计模式之于面向对象系统的设计和开发的作用就有如数据结构之于面向过程开发的作用一般,其重要性和必要性自然不需要我赘述。然而学习设计模式的过程却是痛苦的,从阅读设计模式的圣经GoF 的设计模式:可复用面向对象软件的基础时的枯燥、苦闷、茫无头绪
6、,到有一天突然有一种顿悟;自己去实现 GoF 的 23 中模式时候的知其然不知其所以然,并且有一天在自己设计的系统种由于设计的原因让自己苦不堪言,突然悟到了设计模 第 2 页 共 105 页 k_eckel 设计模式精解GoF 23 种设计模式解析附 C+实现源码 http:/ 式种的某一个正好可以很好的解决问题,到自己设计的 elegant 的系统时候的喜悦与思考;一直到最后向别人去讲解设计模式,别人向你咨询设计模式,和别人讨论设计模式。就如GoF 在其前言中说到:一旦你理解了设计并且有了一种“Aha!”(而不是“Huh?”)的应用经验和体验后,你将用一种非同寻常的方式思考面向对象设计。这个
7、过程我认为是漫长的,painful,但是是非常必要的。经过了的才是自己的,Scott Mayer 在其巨著 Effective C+就曾经说过:C+老手和 C+新手的区别就是前者手背上有很多伤疤。是的在软件开发和设计的过程中,失败、错误是最好的老师,当然在系统开发中,失败和错误则是噩梦的开端和结束,因为你很难有改正错误的机会。因此,尽量让自己多几道疤痕是对的。面向对象系统的分析和设计实际上追求的就是两点,一是高内聚(Cohesion),而是低耦合(Coupling)。这也是我们软件设计所准求的,因此无论是 OO 中的封装、继承、多态,还是我们的设计模式的原则和实例都是在为了这两个目标努力着、贡
8、献着。道不远人,设计模式也是这般道不远人,设计模式也是这般,正如我在设计模式探索(总序)中提到的。设计模式并不是空的理论,并不是脱离实际的教条。就如我们在进行软件开发的过程会很自然用到很多的算法和结构来解决实际的问题,那些其实也就是数据结构中的重要概念和内容。在面向对象系统的设计和开发中,我们已经积累了很多的原则,比如面向对象中的封装、继承和多态、面向接口编程、优先使用组合而不是继承、将抽象和实现分离的思想等等,在设计模式中你总是能看到他们的影子,特别是组合(委托)和继承的差异带来系统在耦合性上的差别,更是在设计模式多次涉及到。而一些设计模式的思想在我们做系统的设计和开发中则是经常要用到的,比
9、如说Template、Strategy模式的思想,Singleton模式的思想,Factory模式的思想等等,还有很多的模式已经在我们的开发平台中扎根了,比如说Observer(其实例为ModelControlView模式)是MFC和Struts中的基本框架,Iterator模式则在C+的STL中有实现等。或许有的人会说,我们不需要设计模式,我们的系统很小,设计模式会束缚我们的实现。我想说的是,设计模式体现的是一种思想,而思想则是指导行为的一切,理解和掌握了设计模式,并不是说记住了 23 种(或更多)设计场景和解决策略(实际上这也是很重要的一笔财富),实际接受的是一种思想的熏陶和洗礼,等这种思
10、想融入到了你的思想中后,你就会不自觉地使用这种思想去进行你的设计和开发,这一切才是最重要的。之于学习设计模式的过程我想应该是一个迭代迭代的过程,我向来学东西的时候不追求一遍就掌握、理解透彻(很多情况也是不可能的),我喜欢用一种迭代的思想来指导我的学习过程。看书看不懂、思想没有理解,可以反复去读、去思考,我认为这样一个过程是适合向我们不是有一个很统一的时间去学习一种技术和知识(可能那样有时候反而有些枯燥和郁闷)。第 3 页 共 105 页 k_eckel 设计模式精解GoF 23 种设计模式解析附 C+实现源码 http:/ GoF 在设计模式一书中也提到,如果不是一个有经验的面向对象设计人员,
11、建议从最简单最常用的设计模式入门,比如 AbstractFactory 模式、Adapater 模式、Composite 模式、Decorator 模式、Factory 模式、Observer 模式、Strategy 模式、Template 模式等。我的感触是确实是这样,至少 GoF 列出的模式我都在开发和设计有用到,如果需要我这里再加上几个我觉得在开发中会很有用的模式:Singleton 模式、Faade 模式和 Bridge 模式。写设计模式解析的目的其实是想把 GoF 的 设计模式 进行简化,变得容易理解和接受。GoF 的设计模式是圣经,但是同时因为设计模式一书是 4 位博士的作品,并且
12、主要是基于 Erich 的博士论文,博士的特色我觉得最大的就是抽象,将一个具体的问题抽象到一般,形成理论。因此 GoF 的这本圣经在很多地方用语都比较精简和抽象,读过的可能都有一种确实是博士写出来的东西的感觉。抽象的好处是能够提供指导性的意见和建议,其瑕疵就是不容易为新手所理解和掌握。我的本意是想为抽象描述和具体的实现提供一个桥接(尽管GoF 在书中给出了很多的代码和实例,但是我觉得有两个不足:一是不完整,结果是不好直接看到演示,因此我给出的代码都是完整的、可编译运行的;二是给出的都是一些比较大的系统中一部分简单实现,我想 GoF 的原意可能是想说明这些模式确实很管用,但是却同时带来一个更大的
13、不好的地方就是不容易为新手理解和掌握),然而这个过程是痛苦的,也可能是不成功的(可能会是这样)。这里面就有一个取舍的问题,一方面我想尽量去简化 GoF的描述,然而思考后的东西却在很多的时候和 GoF 的描述很相似,并且觉得将这些内容再抽象一下,书中的很多表达则是最为经典的。当然这里面也有些许的例外,Bruce Eckel 在其大作Thinking in Patterns一书中提到:Bridge 模式是 GoF 在描述其 23 中设计模式中描述得最为糟糕得模式,于我心有戚戚焉!具体的内容请参看我写的设计模式解析Bridge 模式一文。另外一方面,我又要尽量去避免走到了 GoF 一起,因为那样就失
14、去了我写这个解析的本意了。这两个方面的权衡是很痛苦,并且结果可能也还是没有达到我的本意要求。4 月份是我最不忙的时候,也是我非常忙的时候。论文的查阅、思考、撰写,几个项目的前期准备(文档、Demo等),俱乐部的诸多事宜,挑战杯的准备,学习(课业、专业等各个方面)等等,更加重要的是Visual CMCS(Visual C_minus Compiler System)的设计和开发(Visual CMCS是笔者设计和开发的C_minus语言(C的子集)的编译系统,系统操作界面类似VC,并且准备代码分发和共享,详细信息请参考Visual CMCS的网站和Blog中的相关信息的发布),Visual CM
15、CS1.0(Beta)终于在 4 月底发布了,也在别人的帮助下构建了Visual CMCS的网站(http:/ CMCS 第 4 页 共 105 页 k_eckel 设计模式精解GoF 23 种设计模式解析附 C+实现源码 http:/ 的设计和开发体验了很多的设计模式,比如Factoty模式、Singleton模式、Strategy模式、State模式等等(我有一篇Blog中有关于这个的不完全的描述);另外一方面是这个设计模式解析实际上在这些工作的间隙中完成的,我一般会要求自己每天写一个模式,但是特殊的时候可能没有写或者一天写了不止一个。写这些文章,本身没有任何功利的杂念,只是一个原生态的冲
16、动,反而很轻松的完成了。有心栽花未必发,无心之事可成功,世间的事情可能在很多的时候恰恰就是那样了。最后想用自己在阅读、学习、理解、实现、应用、思考设计模式后的一个感悟结束这个后记:只有真正理解了设计模式,才知道什么叫面向对象分析和设计。k_eckel 写毕于 2005-05-04(五四青年节)1:01 0.3 与作者联系与作者联系 Author K_Eckel State Candidate for Masters Degree School of Computer Wuhan University E_mail 1 创建型模式创建型模式 1.1 Factory 模式模式?问题问题 在面向对象
17、系统设计中经常可以遇到以下的两类问题:1)为了提高内聚(Cohesion)和松耦合(Coupling),我们经常会抽象出一些类的公共接口以形成抽象基类或者接口。这样我们可以通过声明一个指向基类的指针来指向实际的子类实现,达到了多态的目的。这里很容易出现的一个问题 n 多的子类继承自抽象基类,我们不得不在每次要用到子类的地方就编写诸如 new;的代码。这里带来两个问题 1)客户程序员必须知道实际子类的名称(当系统复杂后,命名将是一个很不好处理的问题,为了处理可能的名字冲突,有的命名可能并不是具有很好的可读性和可记忆性,就姑且不论不同程序员千奇百怪的个人偏好了。),2)程序的扩展性和维护变得越来越
18、困难。第 5 页 共 105 页 k_eckel 设计模式精解GoF 23 种设计模式解析附 C+实现源码 http:/ 2)还有一种情况就是在父类中并不知道具体要实例化哪一个具体的子类。这里的意思为:假设我们在类 A 中要使用到类 B,B 是一个抽象父类,在 A 中并不知道具体要实例化那一个 B 的子类,但是在类 A 的子类 D 中是可以知道的。在 A 中我们没有办法直接使用类似于 new 的语句,因为根本就不知道是什么。以上两个问题也就引出了 Factory 模式的两个最重要的功能:1)定义创建对象的接口,封装了对象的创建;2)使得具体化类的工作延迟到了子类中。?模式选择模式选择 我们通常
19、使用 Factory 模式来解决上面给出的两个问题。在第一个问题中,我们经常就是声明一个创建对象的接口,并封装了对象的创建过程。Factory 这里类似于一个真正意义上的工厂(生产对象)。在第二个问题中,我们需要提供一个对象创建对象的接口,并在子类中提供其具体实现(因为只有在子类中可以决定到底实例化哪一个类)。第一中情况的 Factory 的结构示意图为:图 1:Factory 模式结构示意图 1 图 1 所以的 Factory 模式经常在系统开发中用到,但是这并不是 Factory 模式的最大威力所在(因为这可以通过其他方式解决这个问题)。Factory 模式不单是提供了创建对象的接口,其最
20、重要的是延迟了子类的实例化(第二个问题),以下是这种情况的一个 Factory 的结构示意图:第 6 页 共 105 页 k_eckel 设计模式精解GoF 23 种设计模式解析附 C+实现源码 http:/ 图 2:Factory 模式结构示意图 1 图 2 中关键中 Factory 模式的应用并不是只是为了封装对象的创建,而是要把对象的创建放到子类中实现:Factory 中只是提供了对象创建的接口,其实现将放在 Factory 的子类ConcreteFactory 中进行。这是图 2 和图 1 的区别所在。?实现实现?完整代码示例(code)Factory 模式的实现比较简单,这里为了方便
21、初学者的学习和参考,将给出完整的实现代码(所有代码采用 C+实现,并在 VC 6.0 下测试运行)。第 7 页 共 105 页 k_eckel 设计模式精解GoF 23 种设计模式解析附 C+实现源码 http:/ 代码片断 2:Product.cpp/Product.cpp#include Product.h#include using namespace std;Product:Product()Product:Product()ConcreteProduct:ConcreteProduct()coutConcreteProduct.endl;ConcreteProduct:Concret
22、eProduct()代码片断 1:Product.h/Product.h#ifndef _PRODUCT_H_#define _PRODUCT_H_ class Product public:virtual Product()=0;protected:Product();private:;class ConcreteProduct:public Product public:ConcreteProduct();ConcreteProduct();protected:private:;#endif/_PRODUCT_H_ 第 8 页 共 105 页 k_eckel 设计模式精解GoF 23 种设
23、计模式解析附 C+实现源码 http:/ class ConcreteFactory:public Factory public:ConcreteFactory();ConcreteFactory();Product*CreateProduct();protected:private:;#endif/_FACTORY_H_ 代码片断 3:Factory.h/Factory.h#ifndef _FACTORY_H_#define _FACTORY_H_ class Product;class Factory public:virtual Factory()=0;virtual Product*C
24、reateProduct()=0;protected:Factory();private:;ConcreteFactory:ConcreteFactory()coutConcreteFactory.endl;ConcreteFactory:ConcreteFactory()Product*ConcreteFactory:CreateProduct()return new ConcreteProduct();代码片断 4:Factory.cpp/Factory.cpp#include Factory.h#include Product.h#include using namespace std;
25、Factory:Factory()Factory:Factory()第 9 页 共 105 页 k_eckel 设计模式精解GoF 23 种设计模式解析附 C+实现源码 http:/ using namespace std;int main(int argc,char*argv)Factory*fac=new ConcreteFactory();Product*p=fac-CreateProduct();return 0;代码片断 5:main.cpp/main.cpp#include Factory.h#include Product.h?代码说明 示例代码中给出的是 Factory 模式解
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 设计模式精解-GoF 23种设计模式解析 设计 模式 GoF 23 解析
限制150内