设计模式学习心得(持续更新)
本博文仅仅是笔者自己的学习路线,归纳整理了一些好的设计模式资料。
1、策略模式
参考资料:c#设计模式-策略模式 c#设计模式之策略模式
定义是:封装一组算法,每个算法为独立的类,可以相互替代,因为它们有相似的行为。
策略模式主要是将产品共有的部分抽象出来,不同的行为据此抽象作不同的具体实现,最后再有一个Context解耦客户端调用与服务端的实现,客户端是明确知道有哪些行为的。
注意: 如果优化的话,可以使用抽象类,将变化的算法设为抽象方法,或虚方法,这样让子类对该方法进行实现即可,同样可以实现该需求,而且代码重用性应该会更好
2、工厂模式
参考资料:C#设计模式(3)——工厂方法模式 C#设计模式(1)——简单工厂模式 C#设计模式(2)——工厂模式 工厂模式-C#改良实现
工厂模式主要是用来创建产品(即对象),在指定的工厂中构建指定的产品。整个的构建过程都是解耦的。
由简单工厂模式到工厂模式的演进,是设计模式的原则之一:开放封闭原则 推进的。这一点在我们日常开发中有很明显的体现,我个人也是"后知后觉"。代码的开发应该对扩展开放,对修改封闭。
对比了下策略模式与工厂模式的实现,我发现其实可以很简单实现两者的相互转换:抽象和具体都是变动,策略模式中的Context层替换为工厂模式中的工厂层,就OK了。但是两者的含义不一样。从代码来分析,策略模式是在客户端已经明确了产品,工厂模式则是将产品委托给了工厂来创建。可参考 简单工厂模式与策略模式的区别。
3、建造者模式
参考资料:C#设计模式-建造者模式 C#设计模式之四建造者模式(Builder Pattern)【创建型】 建造者模式-C#改良实现
建造者模式主要用于“分步骤来构建一个复杂的对象”,针对的产品/对象的构建过程。
微软FCL中的StringBuilder类的实现就是变种的Builder模式,其实现值得借鉴。
建造者模式的实现与工厂模式的实现其实比较相似。在工厂方法模式里,我们关注的是一个产品整体,无须关心产品的各部分是如何创建出来的;但在建造者模式中,一个具体产品的产生是依赖各个部件的产生以及装配顺序,它关注的是“由零件一步一步地组装出产品对象”。简单地说,工厂模式是一个对象创建的粗线条应用,建造者模式则是通过细线条勾勒出一个复杂对象,关注的是产品组成部分的创建过程。可参考 工厂方法模式VS建造者模式
4、模板方法
参考资料:模板模式的应用 C#设计模式(14)——模板方法模式
我对模板方法模式的理解就是:抽象类和多态的体现在这个模板方法中,并得到了完美的实现与应用。
定义一个抽象类,类中的抽象方法是可变的,延迟到子类中实现,根据子类的行为做不同的实现。类中的非抽象方法则是模板方法,定义了模板的内容和执行顺序。其次若是有公共的部分也可以在类中的非抽象方法中实现。
5、观察者模式
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
观察者模式有四个角色:抽象主题、具体主题、抽象观察者、具体观察者。
抽象主题:把所有观察者对象的引用保存到一个聚集里,每个主题都可以有任何数量的观察者。
具体主题:将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。
抽象观察者:为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
具体观察者:实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。
可参考:C#设计模式-观察者模式 观察者模式-C#实现
6. 状态模式
当一个对象的内部状态改变时允许改变它的行为。
状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。
Context:状态管理器,维护一个ConcreteState子类的实例,这个实例定义了当前的状态。
State:抽象状态类,将所有可能的状态都抽象为具体的行为(方法)或是状态(字段)。
ConcreteState:具体状态,每一个子类实现的一个与Context的一个状态相关的行为,并完成状态的切换。
状态模式与策略模式都可以用来替换掉switch..case或是if...else...冗长的条件判断分支,区别在于,如果条件状态之间有关联或是依赖关系,比如宾馆房间的状态,银行账户的状态等之间有关联及依赖关系,此时应该用状态模式来做切换替代,但是对于条件状态之间没有什么关系的比如,快递点的选择等选择性的条件状态,使用策略模式比较合适。
状态模式替换switch...case可参考 C#设计模式--状态模式 策略模式替换switch...case...可参考 策略模式重构switch/case分支代码
7. 代理模式
三个角色:代理接口、委托类、代理类。
委托类是代理接口的具体实现,而代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类、以及事后处理消息等。代理类同样也实现代理接口,只是代理类的对象并不真正实现服务,而是通过调用委托类的对象的相关方法来提供特定的服务。
动态代理:代理类在程序运行时创建的代理方式。
如果委托类很多的话,那么静态代理的方式将会产生大量的代理类,这不利于维护,会产生多个弊端,所以就有了动态代理。
动态代理与AOP紧密相关,AOP说白了就是在某个实例方法的调用前后增加相应地业务逻辑或是处理逻辑,为了方便以及实际的开发,我们会创建某个实例类的动态实例,这就是动态代理的作用了,其次在动态代理中执行指定的方法前后增加逻辑即可,这就是AOP与动态代理的紧密联系了。绝大数的框架中,会创建一个拦截器,在指定的拦截方法中调用动态代理实例方法,并增加相应地业务逻辑或是处理逻辑即完成了AOP。简单的实现,可以在创建动态代理类实例调用指定方法的前后增加逻辑即可。