我的设计模式总结
各位小牛大牛老鸟菜鸟们好,欢迎参观我的设计模式世界.这个世界我已经总结多年了,现在才刚刚成型.butihaveadream,梦想所有开发者都能一夜之间认清所有设计模式,还幻想以后大家认识设计模式时,必首先google本文,嘿嘿.
前辈同仁们已经总结过很多,至今首页上设计模式的文章仍然层
出不穷.但我总认为,在gof的23个设计模式提出多年了,该需要些变化和扩展了.特别适用于(或mono)的设计模式,好像没有系统的总结.新年伊始,推出这篇总结,我个人不喜欢人云亦云,对设计模式的整体,以及其中一些模式,有独特的理解,欢迎指点.
引用阿彬同学对术和道的论述:在真正好的程序员心中,设计模式是“术”,设计模式背后的用意才是“道”.为什么要用某个模式,是为了解决什么问题?紧耦合?可测性差?扩展性差?他们写代码时,心中已无设计模式,用心设计、简单设计;在可测性、可扩展性和复
杂程度之间做巧妙的权衡取舍;当他们写完代码,已经不知不觉合理地使用了若干设计模式.——其实我这句话也说错了,代码永远没有“写完”的一天,他们会不断重构它,重构出设计模式,或者重构掉设计模式.
本文所列的设计模式基于,有些我认为是鱼目混珠,另外补充了几个模式.我认识设计模式的方式有点不同,不想照搬一个模式的定义,更关心它的特征,即长得像什么,能做什么,为什么要这样做,这应该更方便新人理解.此外,还设法注意不同设计模式之间的联系.由于时间篇幅关系,无法贴出太多代码,不过会指出多数模式在bcl中的实现.
设计模式一般分为创建、构造、行为三类.我遵循这个分类,而做了一点调整,如builder模式我放到构造分类中.加上并发模式,共四类.并发类的模式稍后再补充.
除这个传统的分类方式外,我会从另外三个角度为设计模式概括
总结.
第一个角度就是语言的角度,本文主要基于c#/vb(mono).设计模式并非架构模式,它与语言特性紧密相关.不少模式在不同语
言实现不同,比如单例模式.有些模式则是某种语言独有的,比如
raii是c++专用模式.
第二个角度,是开发领域角度.编程开发可简单分为两大领域,即框架开发和应用开发.明白这两个领域的区别和联系,对理解设计模
单例模式的几种实现方式
式的实现非常重要.在框架开发中,设计模式应用频率要高得多,有些模式基本上只出现于框架中.做应用开发,经常会“应用”框架实现
的设计模式,不少人用了而也稀里糊涂地不知道.
“应用”可能不算很确切的词儿,还是来个图吧,表示通常情况下,框架层和应用层合作的设计模式完整实现:
我还是先举个最简单的entityframework的例子吧,免得被鄙视.如今ef比较钟情,代码如下:
publicclasspersonmap//这是对抽象的扩
展:entitytypeconfiguration<person>//这是ef提供的抽象{publicpersonmap(){this.haskey(p=>p.idcard);//设idcard为主键属
性}}publicclassmydbcontext:dbcontext{publicmydbcontext():ba
se("entities"){}///<summary>///在这个方法里能做的事情,就是api///</summary>protectedoverridevoidonmodelcreating(dbmode lbuildermodelbuilder){figurations.add(newpe
rsonmap());//这自然就是“应
用”}publicdbset<person>persons{get;set;}}
至于这是哪种模式,希望把本文看完就明白了.
不是做应用开发就不必了解设计模式,恰恰相反,做应用开发因为接触得少,更需要主动了解设计模式,以免成日陷于业务海洋中成了
砖家,专门搬砖盖永远盖不到顶的业务大楼.而且有一些模式,应用开发中用的更频繁.
不管是应用还是创建完整的实现,都可以说使用了这个模式.面试官问你用过哪些模式的时候,随便拾三两个例子就行,别让人家太崇拜你,嘿嘿.
我们从上图可见,设计模式实现分为四部分.api和抽象可以合算一部分,应该称之“采用某设计模式的解决方案”,简称解决方案吧.然而不是所有模式的解决方案都需要抽象部分,没有抽象自然也没有扩展.根据设计模式是否提供扩展机制这点,可以分为扩展模式和非扩展模式,这就是第三个角度.可扩展的模式理解难度略大,不过也更有趣.
一般地讲,构造模式都是可扩展的,行为模式都是非扩展的,而创建模式二者兼有.
一、创建模式
1.工厂方法模式factorymethod
这个模式很简单,就是不直接通过构造函数(用new关键字),而是通过调用某个方法(偶尔用属性)得到一个对象.比如ate(url)方法,返回httpwebrequest对象.
下面许多其他模式都会用工厂方法,因为我们往往不知不觉就在
用它,就不列举了.这是一个最基础最底层的模式.
灵活应用泛型可以让大大减少创建工厂方法的工作,如用comparer<t>.create(comparion<t>)方法,不用写不同类型的比较器类,就能创建出针对不同类型的比较器.
2.抽象工厂模式abstractfactory
工厂就是指那种专门提供工厂方法的类.如果业务逻辑复杂起来,而如果想根据需要,分别得到某一批而不是某一个类的实例,就需要
有相应的一批工厂类.如果用抽象类或接口规定了这批工厂类的工厂
方法,就是抽象工厂模式.一般来说,若工厂源自抽象工厂,其“产品”也继承自某抽象类或接口.
此模式比上个复杂得多,但其实很好理解.曹操曾吟,对酒当歌,人生几何.何以解忧,唯有杜康.他一定想不到如今还有拉菲产葡萄酒,
茅台产白酒,青啤产啤酒.如果曹公再世,粉丝想为他写个程序,就可
以定义一个抽象工厂:酒厂,拉菲等品牌继承自酒厂,产品白酒啤酒都
是酒,继承自酒类.
上面提到的task.factory,是一个taskfactory对象.像taskfactory这种独立工厂不多见,因为若只要得到某个特定类的实例,通常像webrequest/image那样在自身加一个静态工厂方法即可.
这是个大家最熟悉的模式,被广泛应用在框架设计中,下表列了几个bcl的例子.这种模式很好识别,因为工厂类名多带factory,和接口开头的i,成了标准,不过也有一些深藏不露.
抽象工厂
工厂类
产品定义
产品类
ihttphandler
page,staticfilehandler等icontrollerfactory
icontroller
controller
sqldbfactory
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论