C# 23种设计模式
创建型模式
工厂方法(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模式需要额外的工作。
|