C# 23种设计模式

设计模式(Design pattern)是一套被反复使用、多数人知晓的、通过分类编目的、代码设计经验的总结。html

使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的;设计模式使代码编制真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构同样。算法

整体来讲设计模式分为三大类:数据库

建立型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。设计模式

结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 浏览器

行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。网络

 

建立型模式
工厂方法(Factory Method)
在工厂方法模式中,工厂方法用来建立客户所须要的产品,同时还向客户隐藏了哪一种具体产品类将被实例化这一细节。工厂方法模式的核心是一个抽象工厂类,各类具体工厂类经过抽象工厂类将工厂方法继承下来。如此使得客户能够只关心抽象产品和抽象工厂,彻底不用理会返回的是哪种具体产品,也不用关系它是如何被具体工厂建立的。

抽象工厂模式(Abstract Factory)
抽象工厂模式的主要优势是隔离了具体类的生成,使得客户不须要知道什么被建立了。犹豫这种隔离,更换一个具体工厂就变得相对容易。全部的具体工厂都实现了抽象工厂中定义的那些公共接口,所以只需改变具体工厂的实例,就能够在某种程度上改变这个软件的系统的行为。另外,应用抽象工厂模式符合GRASP纯虚构的模式,能够实现高内聚低耦合的设计目的,所以抽象工厂模式获得了普遍应用。

建造者模式(Builder Pattern)
建造者模式将一个复杂对象的生成责任做了很好的分配。它把构造过程放在指挥者的方法中,把装配过程放到具体建造者类中。建造者模式的产品之间都有共通点,但有时候,产品之间的差别性很大,这就须要借助工厂方法模式或抽象工厂模式。另外,若是产品的内部变化复杂,Builder的每个子类都须要对应到不一样的产品去作构建的动做、方法,这就须要定义不少个具体建造类来实现这种变化。

单件模式(Single Pattern)
Singleton单例模式为一个面向对象的应用程序提供了对象惟一的访问点,无论它实现何种功能,此种模式都为设计及开发团队提供了共享的概念。然而,Singleton对象类派生子类就有很大的困难,只有在父类没有被实例化时才能够实现。值得注意的是,有些对象不能够作成Singleton,好比.net的数据库连接对象(Connection),整个应用程序同享一个Connection对象会出现链接池溢出错误。另外,.net提供了自动废物回收的技术,所以,若是实例化的对象长时间不被利用,系统会认为它是废物,自动消灭它并回收它的资源,下次利用时又会从新实例化,这种状况下应注意其状态的丢失。

原型模式(Protype Pattern)
原型模式获得了普遍的应用,特别是在建立对象成本较大的状况下(初始化需占用较长时间,占用太多CPU资源或网络资源。好比经过Webservice或DCOM建立对象,或者建立对象要装载大文件),系统若是须要重复利用,新的对象能够经过原型模式对已有对象的属性进行复制并稍做修改来取得。另外,若是系统要保存对象的状态而对象的状态变化很小,或者对象自己占内存不大的时候,也能够用原型模式配合备忘录模式来应用。相反地,若是对象的状态变化很大,或者对象占用内存很大,那么采用状态模式会比原型模式更好。原型模式的缺点是在实现深层复制时须要编写复杂的代码。

结构型模式
适配器模式(Adapter Pattern)
适配器模式能够将一个类的接口和另外一个类的接口匹配起来,使用的前提是你不能或不想修改原来的适配器母接口(adaptee)。例如,你向第三方购买了一些类、控件,可是没有源程序,这时,使用适配器模式,你能够统一对象访问接口。但客户调用可能须要变更。

桥接模式(Bridge Pattern)
桥接模式能够从接口中分离实现功能,使得设计更具扩展性,这样,客户调用方法时根本不须要知道实现的细节。
桥接模式减小了子类,假设程序要在2个操做系统中处理6种图像格式,纯粹的继承就须要(2*6)12个子类,而应用桥接模式,只须要(2+6)8个子类。它使得代码更清洁,生成的执行程序文件更小。  
桥接模式的缺陷是抽象类与实现类的双向链接使得运行速度减慢。

组合模式(Composite Pattern)
组合模式能够清楚地定义分层次的复杂对象,表示对象的所有或部分层次,使得增长新部件也更容易,由于它让客户忽略了层次的不一样性,而它的结构又是动态的,提供了对象管理的灵活接口。组合模式对于树结构的控制有着神奇的功效,例如在人力资源系统的组织架构及ERP系统的BOM设计中,组合模式获得重点应用。
组合模式的缺陷是使得设计变得更加抽象。对象的商业规则若是很复杂,则实现组合模式具备很大挑战性,而且,不是全部的方法都与叶部件子类有关联。

装饰模式(Decorator Pattern)
装饰模式提供了比静态继承更好的柔韧性,它容许开发一系列的功能类用来代替增长对象的行为,这既不会污染原来对象的源码,还能使代码更容易编写,使类更具扩展性,由于变化都是由新的装饰类来完成。还能够创建链接的装饰对象关系链。
须要注意的是,装饰链不宜过长。装饰链太长会使系统花费较长时间用于初始化对象,同时信息在链中的传递也会浪费太多的时间。这个状况比如物品包装,包了一层又一层,大包套小包。另外,若是原来的对象接口发生变化,它因此的装饰类都要修改以匹配它的变化。派生子类会影响对象的内部,而一个Decorator只会影响对象的外表。

架构

外观模式(Façade Pattern)
外观模式提供了一个简单且公用的接口去处理复杂的子系统,而且没有减小子系统的功能。它遮蔽了子系统的复杂性,避免了客户与子系统直接连接,它也减小了子系统与子系统间的链接,每一个子系统都有它的Facade模式,每一个子系统采用Facade模式去访问其余子系统。外观模式的劣势就是限制了客户的自由,减小了可变性。

享元模式(Flyweight Pattern)
Flyweight模式须要你认真考虑如何能细化对象,以减小处理的对象数量,从而减小存留对象在内存或其余存储设备中的占用量。然而,此模式须要维护大量对象的外部状态,若是外部状态的数据量大,传递、查找、计算这些恶数据会变得很是复杂。当外部和内部的状态很难分清时,不宜采用flyweight模式。

代理模式(Proxy Pattern)
当对象在远程机器上,要经过网络来生成时,速度可能会慢,此时应用Remote Proxy模式,能够掩蔽对象由网络生成的过程,系统的速度会加快;对于大图片的加载,Virtual Proxy模式可让加载在后台进行,前台用的Proxy对象使得总体运行速度获得优化;Protect Proxy能够验证对真实对象的引用权限。
代理模式的缺陷是请求的处理速度会变慢,而且实现Proxy模式须要额外的工做。

行为型模式
职责链模式(Chain of Responsibility)
责任链模式能够减小对象的链接,为对象责任分配增长了很大的灵活性。该模式容许把一组类做为一个类来使用,而且在类的组合中,一个类的事件能够发送到另外一个类并由其处理。
责任链模式一般应用与图形用户界面中,窗体的部件可能会包含其余几个小部件,就如同Windows窗体应用程序中,控件中又能够放置其余控件,控件边界会决定是否处理事件,或者将事件传递给父控件来处理。
另外,责任链还会以树状出现,这样,一个事件能够传给多个类,或者,多个类的信息能够提交到一个类。树状责任链可以提供更灵活的技巧,但缺点是信息在树中容易迷失。

命令模式(Command Pattern)
命令模式分离了接受请求的对象与实现处理请求工做的对象,这样,已经存在的类能够保持不变,使得增长新类的工做更简单。例如,不少软件的宏命令就提升了系统的自动化程度。
命令模式还能够分离用户界面和业务对象,下降系统的耦合度。
可是,命令模式最主要的缺陷就是,类的数量增长了,系统变得更复杂,程序的调试工做也相应变得困难。

解释器模式(Interpreter Pattern)
解释器模式的做用很强大,它使得改变和扩展文法变得容易,实现文法也变得简单明了,不少编译器,包括文本编辑器、网页浏览器及VRML都应用解释器模式。
解释器模式的缺陷就是,由于文句会分析成树结构,解释器须要递归访问它,因此效率会受影响。这种状况开发人员会有所体会,编译整个工程源码耗费时间都比较长。

模版方法模式(Template Method)
模版方法模式在一个类中形式化地定义算法,而由它的子类实现细节的处理。模版方法模式的优点是,在子类定义处理算法时不会改变算法的结构。
模版方法的特色在于,每一个不一样的实现都须要定义一个子类,这也复合高内聚的责任分配模式,不能说成是它的缺点。

迭代器模式(Iterator Pattern)
迭代器模式支持在汇集中移动游标,使得访问聚合中的元素变得简单,简化了汇集的接口,封装了聚合的对象。
迭代器模式还能够应用于对树结构的访问,程序不须要从头逐行代码查找相应位置,可控制到从子集开始查找,对于加快程序的运行速度有很重要的做用。
迭代器模式的缺点是聚合密切相关,增长了耦合。但将这种耦合定义在抽象基类,可解决这个问题。

观察者模式(Oberver Pattern)
观察者模式抽象了被观察对象与观察者对象的链接,提供了广播式的对象间通讯,而且容易增长新的观察者对象。观察者模式的缺陷是对象间的关系难以理解,在某种状况下会表现低效能。

中介者模式(Mediator Pattern)
中介者模式分离了两个同事类,简化了对象协议,中央控制对象交互,从而使个体对象变得更容易且更简单,由于它不须要传递数据给其余个体对象,仅仅传给中介者就能够了。个体对象不须要具备处理内部交流的逻辑,因此更加突出它的面向对象特性。

备忘录模式(Memento Pattern)
Memento模式保存了封装的边界,一个Memento对象是另外一种原发器对象的表示,不会被其余代码改动。这种模式简化了原发器对象,Memento只保存原发器的状态。采用堆栈备忘对象,能够实现屡次取消操做。

状态模式(State Pattern)
状态模式在对象内保存特定的状态而且就不一样的状态履行不一样的行为,它使状态的变化显得清晰明了,也很容易建立对象的新状态。
状态模式在工做流或游戏等各类系统中大量使用,例如在政府 OA系统中,一个批文的状态有多种:未办、正在处理、正在批示、正在审核和已经完成等各类状态。在网络游戏中,一个游戏活动存在开始、开玩、正在玩、输赢等各类状态。使用状态模式就能够实现游戏状态的总控,而游戏状态决定了游戏的各个方面。

策略模式(Strategy Pattern)
策略模式提供了替代派生的子类,并定义类的每一个行为,剔除了代码中条件的判断语句,使得扩展和结合新的行为变得更容易,根本不须要变更应用程序。策略模式能够避免使用多重条件转移语句,系统变得更新灵活。应用策略模式会产生不少子类,这符合高内聚的责任分配模式。

访问者模式(Visitor Pattern)Visitor(访问者)模式使得增长新的操做变得容易,它能够收集有关联的方法,而分离没有关联的方法,特别适用于分离由于不一样缘由而变化的事物,如“在男人中分离出男孩”。但Visitor模式经常要打破对象的封装性,visitor与element须要达成某些共识。