常用设计模式总结

来源:互联网 发布:java message类 编辑:程序博客网 时间:2024/04/28 04:16

故纸堆里翻出来的收藏博文,稍作整理转载以作备忘。

--------------------------------------------------------------

常用设计模式总结

据说在欧洲曾经有个男孩自幼酷爱数学,但无奈家贫中学就辍学,但他一直自己学习,后来他感到自己突然发现了一个重大理论,并以这个理论的无比完美而欣喜,直到有一天,一次进城在书店看书的时候,发现原来他发现的理论就是微积分,并且已经存在1百多年了,你可以想象这个男孩当时的心情,最后他自杀了。

随着经历的软件越来越多,发现设计模式越来越重要,特别是当你绞尽脑汁为了解决一个问题构想出一个完美的解决方案之时,你感觉到自己欣喜若狂,甚至开始飘飘然的自我陶醉于自己的聪明才智,但是你突然看到你这种方案原来就是其中的一个前人早已总结好的模式时,你会不会变得非常懊恼呢!反正我是有过这样的经历。当然这里的模式没有微积分的历史地位和对社会科学的贡献重要,我们也不可能去模仿那个男孩,但是我们如果主动学习设计模式确实可以少走不少弯路。

下面我就结合自己的学习和应用做一些简单总结。

一、经典书籍

设计模式的经典书籍,第一本当然就是四人帮的《设计模式》,还有其他人的一些比如《设计模式精解》、《C#设计模式》等。我个人感觉所有设计模式的书籍都很难懂,别想一次看懂,特别是如果你没有接触过设计模式,再如果你没有开发经验那就更困难了。

二、编码设计中的几个原则

1OCP法则:开闭法则(Open-Closed Principle

一个软件系统应当对扩展开放,对修改关闭

优点:原则的描述就是其优点所在,

1)通过扩展已有软件系统,可以提供新的行为,以满足对软件的新的需求,使变化中的软件有一定的适应性和灵活性。

2)已有软件模块,特别是最重要的抽象层模块不能再修改,这使变化中的软件系统有一定的稳定性和延续性

实现原则就是抽象。

2LSP法则:里氏代换原则(Liskov Substitution Principle

把抽象借口和实现分离

这是继承的特征,子类型(subtype)必须能够替换它们的基类型。

3DIP法则:依赖倒置原则Dependence Inversion Principle

原则表述:抽象不应当依赖于细节;细节应当依赖于抽象;要针对接口编程,不针对实现编程。具体讲就是要依赖于抽象,不要依赖于具体。

实现原则就是,传递参数,或者在组合聚合关系中,尽量引用层次高的类。

4ISP原则:接口隔离原则(Interface Segregation Principle

原则:每一个接口应该是一种角色,不多不少,不干不该干的事,该干的事都要干。这类似编码原则中的最小权限法则。

5CARP法则:合成/聚合复用原则(Composite/Aggregate Reuse Principle

也叫做CRP法则:合成复用原则(CompositeReuse Principle

原则:要尽量使用合成/聚合,尽量不要使用继承。这就是有一个和是一个的问题。

6、LoD法则:迪米特原则(Law of Demeter

又叫LKP法则:最少知识原则(LeastKnowledge Principle

也就是说,一个对象应当对其它对象有尽可能少的了解。其它表述:这实际上就是设计高内聚低耦合的要求,有人形象地称谓不要和陌生人讲话

三、设计模式的分类

四人帮有两种分类模式,一是按照目的來分,分为创建型、结构型、行为型,二是按照范围来分,可分为类模式和对象模式。

创建型模式:与类对象的创建相关。

结构行模式:主要处理类和对象的组合关系。

行为模式:主要为对类或对象如何怎样交互和如何分配职责进行描述。

类模式:主要处理类和子类之间的关系,这些关系通过继承建立,是静态的,在编译时刻便确定下来了。

对象模式:主要处理对象间的关系,在运行时刻是可变的,更具动态性,大部分的模式都是对象模式。

分类常见下图


关于工厂模式为类模式、抽象工厂模式为对象模式的分析:

首先这两个都是创建型模式,创建型类模式和对象模式的主要区别是:类模式使用继承关系,把对象的创建延迟的子类,对象模式把对象的创建延迟到另一个对象中。

使用工厂模式目的是为了创建对象,但是在创建的这个对象的时候你需要在不同的环境下创建不同的对象,这个不同的环境就有工厂类的子类来决定,因此基类的创建方法为抽象方法,子类类实例化这个方法,这里创建对象的子类对象和基类是继承关系确定,因此应该为类模式。再來看一下抽象工厂模式的创建过程,首先你要创建的对象可能是隶属于多个系列,比如可能是不同操作系統的控件、或是不同难度基本的游戏角色等等,这时你所创建的对象所需的工厂就是由抽象工厂的子类实现(这里看和工厂模式没有区别),但是这个子类根据不同的环境对应不不同的子类对象,是运行时决定的,因此这里应该是对象型创建模式,当然如果这里永远只产生一个系列的产品,就退化为工厂模式了,也就变成了类模式了,如果在工厂模式中要求新增工厂的子类,并且这些不同的子类创建相同的产品(比如都是按钮、风格不同)这时工厂模式就上升为抽象工厂模式了,也就变成对象模式了。因此我的理解是区别创建型类模式和对象模式关键看创建产品的工厂类对象是不是动态的加以区别即可。  

四、我最常用的设计模式

根据我的经验我把我经常用到的设计模式在这里做个总结,按照我的经验,它们的排序如下:1)单件模式、2)抽象工厂模式和工厂模式、3)适配器模式、4)装饰模式、5)观察者模式、6)外观模式其他模式目前还很少用到。

1、单件模式

这是用的最多的模式,每一个正式的软件都要用它,全局配置、唯一资源、还有一个就是所有的工厂我都设计为单件模式,因此它的使用量大于工厂模式和抽象工厂模式之和。

2、工厂模式和抽象工厂模式

为了在程序代码中避免出现大量的New,因此我编写的软件代码这两三年基本都使用了工厂,由于深受受王咏武大侠关于舍熊掌取小鱼的影响,因此我较多地选用工厂模式,感觉确实有扩展需要的情况下才使用抽象工厂模式,其实工厂模式就是一个抽象工厂的特例,扩展为抽象工厂也非常容易。

可参考《C++设计模式之一-工厂模式(简单工厂、工厂和抽象工厂)》。

3、适配器模式

适配器模式有两种类的适配器和对象适配器,对象适配器更多一些,对象适配器的优点在很多大侠的著作了已经论述n次了,我这里不多啰嗦,我用的较多的原因还有一个,我从C++转到C#,由于C#不支持多重继承,我又不比较懒,较少定义interface,因此大多数情况下用C#时也只能使用对象适配器模式了。其实适配器和装饰模式功能上有很大的相似性,在下面的装饰模式中加以论述。

4、装饰模式

也叫油漆工模式,装饰模式和适配器模式相似都是用来利用现成代码加以调整来满足新的需求,其实采用设计模式的目的之一就是复用,这两个模式正是复用的体现。当你要用这两种模式的时候都是为你现有软件新增新的功能,一般情况下,如果你是让你的软件新增新的功能操作,你一般要用装饰模式,你如果要为软件新增功能支持,你最好选择适配器模式,你如果想为你的类新增操作你用装饰模式,你如果要引入其他来源的现成代码,你用适配器模式。  

5、观察者模式

这个模式我用的多一个原因就是它可以实现事件功能,当然在C#中可以直接使用事件,但是在C++中却是用可以用此模式发挥的淋漓尽致了,网上曾经的一个考题(猫大叫一声,主人醒来,耗子跑开),就是使用这个模式的最好应用。

6、外观模式

开发就是能复用的地方就复用,这样才能节省资源,提高效率,外观模式也是一个提供复用其他现成代码的解决方案,你需要实现一个功能,可能现成的代码中就有此功能,但是现成代码可能远远多于你所需要的功能,此时你把这些功能封装起来,再重新提供一个你所需要的接口,这就是这个模式的精髓所在。

 

参考:

《大话设计模式》

《深入浅出设计模式》

《敏捷软件开发原则、模式与实践》

《设计模式--可复用面向对象软件的基础》

《设计模式精解-GoF 23种设计模式解析附C++实现源码》

《面向对象的设计模式(C++ 版)-Tiger Consultation Studio》


《易学设计模式分类》

C#设计模式迷你速查手册》 

JAVA与模式》

《Java之美之设计模式23式:1-5、6-12、13-18、19-23》

0 0