14,模板方法模式
http://www.cnblogs.com/guoshiandroid/archive/2011/06/26/2090784.html
模板方法模式解释:
模板方法模式(Template Method Pattern):定义一个操作中算法的骨架(或称为*逻辑),将一些步骤(或称为基本方法)的执行延迟到其子类中,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
英文定义为:Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm‘s structure.。
模板方法模式所涉及的角色如下:
抽象类(AbstractClass):定义了一到多个的抽象方法,以供具体的子类来实现它们;而且还要实现一个模板方法,来定义一个算法的骨架。该模板方法不仅调用前面的抽象方法,也可以调用其他的操作,只要能完成自身的使命。
具体类(ConcreteClass):实现父类中的抽象方法以完成算法中与特定子类相关的步骤。
模板方法模式深入分析:
有人说,如果你只会一个设计模式的话,那么这个设计模式就一定是模板方法模式。
模板方法模式是一种非常简单的设计模式,但是也应用非常广泛的设计模式。模板方法模式采用继承的方式实现算法的异构,其关键点就是将通用算法封装在抽象基类中,并将不同的算法细节放到子类中实现。
模板方法模式获得一种反向控制结构的效果,这也是面向对象系统的分析和设计中一个原则DIP(依赖倒置:Dependency Inversion
Principles)。其含义就是父类调用子类的操作(高层模块调用低层模块的操作),低层模块实现高层模块声明的接口。这样控制权在父类(高层模块),低层模块反而要依赖高层模块。
模板方法模式的优缺点分析:
优点:
使用模板方法模式,在定义算法的骨架的同时,可以很灵活地实现具体的算法,满足用户灵活多变的需求
缺点:
虽然使用模板方法模式可以很*的实现具体的算法,但如果算法的骨架有改变的话,这需要改变抽象类。
模板方法模式的实际应用简介:
模板模式适用于以下的情况:
第一:一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
第二:各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。其实这可以说是一种好的编码习惯了。
第三:控制子类扩展。模板方法只在特定点调用操作,这样就只允许在这些点进行扩展。如果你不愿子类来修改你的模板方法定义的框架,你可以采用两种方式来做:一是在API中不体现出你的模板方法;二、将你的模板方法置为final就可以了。可以看出,使用模板方法模式可以将代码的公共行为提取出来,达到复用的目的。而且,在模板方法模式中,是由父类的模板方法来控制子类中的具体实现。这样你在实现子类的时候,根本不需要对业务流程有太多的了解。
温馨提示:
模板方法模式是一种运用非常广泛的设计模式,在Servlet和很多著名的框架中都有大量的应用。一般而且,在我们使用框架的时候,往往都是框架给我们实现设计好了算法骨架,同时也实现了一些事务、权限控制等,我们要做的就是按照事先规划好的流程,实现相应的业务方法。
15,观察者模式
http://www.cnblogs.com/guoshiandroid/archive/2011/07/27/2118796.html
观察者模式解释:
观察者模式(Observer Pattern)又名发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式、从属者(Dependents)模式,观察者模式定义了定义了一种对象间的一种一对多的依赖关系,当一个对象的状态发生变化的时候,所有依赖于它的对象都得到通知并且被自动刷新对象状态。
观察模式提供给关联对象的一种同步通信的手段,使得某个对象和依赖它的对象之间保持状态的同步。
英文定义为:Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically。
观察者模式所涉及的角色如下:
抽象被观察者(Subject):被观察的对象,当需要被观察的状态发生改变时,被观察者需要通知队列中的所有观察者对象。Subject可以有任意多个观察者对象,被观察者需要维持一个观察者对象的队列列表,通过这种维持是指添加、删除、通知被观察者。
具体被观察者(ConcreteSubject):被观察者的具体的实现。包含一些基本的属性及其他操作。
抽象观察者(Observer):是一个接口或者抽象类。当被观察者的状态发生改变时,观察者对象将通过一个回调函数得到通知。
具体观察者(ConcreteObserver):观察者的具体实现。存储有关的状态,这些状态应与被观察者的状态保持一致。实现Observer的更新接口以使得自身状态和目标的状态保持一致。在本角色内也可以维护一个指向具体的被观察者对象的引用。
观察者模式深入分析:
观察者模式(Observer)完美的将观察者和被观察的对象分离开。举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。面向对象设计的一个原则是:系统中的每个类将重点放在某一个功能上,而不是其他方面。一个对象只做一件事情,并且将他做好。观察者模式在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。
观察者模式有很多实现方式,从根本上说,该模式必须包含两个角色:观察者和被观察对象。在刚才的例子中,业务数据是被观察对象,用户界面是观察者。观察者和被观察者之间存在“观察”的逻辑关联,当被观察者发生改变的时候,观察者就会观察到这样的变化,并且做出相应的响应。如果在用户界面、业务数据之间使用这样的观察过程,可以确保界面和数据之间划清界限,假定应用程序的需求发生变化,需要修改界面的表现,只需要重新构建一个用户界面,业务数据不需要发生变化。
“观察”不是“直接调用”
实现观察者模式的时候要注意,观察者和被观察对象之间的互动关系不能体现成类之间的直接调用,否则就将使观察者和被观察对象之间紧密的耦合起来,从根本上违反面向对象的设计的原则。无论是观察者“观察”观察对象,还是被观察者将自己的改变“通知”观察者,都不应该直接调用。
实现观察者模式有很多形式,比较直观的一种是使用一种“注册——通知——撤销注册”的形式。下面的三个图详细的描述了这样一种过程:
1:观察者(Observer)将自己注册到被观察对象(Subject)中,被观察对象将观察者存放在一个容器(Container)里。
2:被观察对象发生了某种变化(如图中的SomeChange),从容器中得到所有注册过的观察者,将变化通知观察者。
3:观察者告诉被观察者要撤销观察,被观察者从容器中将观察者去除。
观察者将自己注册到被观察者的容器中时,被观察者不应该过问观察者的具体类型,而是应该使用观察者的接口。这样的优点是:假定程序中还有别的观察者,那么只要这个观察者也是相同的接口实现即可。一个被观察者可以对应多个观察者,当被观察者发生变化的时候,他可以将消息一一通知给所有的观察者。基于接口,而不是具体的实现——这一点为程序提供了更大的灵活性。
观察者模式的优缺点分析:
Observer模式的优点是实现了表示层和数据逻辑层的分离,并定义了稳定的更新消息传递机制,类别清晰,并抽象了更新接口,使得可以有各种各样不同的表示层(观察者)。但是其缺点是每个外观对象必须继承这个抽像出来的接口类,这样就造成了一些不方便,比如有一个别人写的外观对象,并没有继承该抽象类,或者接口不对,我们又希望不修改该类直接使用它。虽然可以再应用Adapter模式来一定程度上解决这个问题,但是会造成更加复杂烦琐的设计,增加出错几率。
观察者模式的效果有以下几个优点:
(1)观察者模式在被观察者和观察者之间建立一个抽象的耦合。被观察者角色所知道的只是一个具体现察者聚集,每一个具体现察者都符合一个抽象观察者的接口。被观察者并不认识任何一个具体观察者,它只知道它们都有一个共同的接口。由于被观察者和观察者没有紧密地耦合在一起,因此它们可以属于不同的抽象化层次。
(2)观察者模式支持广播通信。被观察者会向所有的登记过的观察者发出通知。
观察者模式有下面的一些缺点:
(1)如果一个被观察者对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
(2)如果在被观察者之间有循环依赖的话,被观察者会触发它们之间进行循环调用,导致系统崩溃。在使用观察考模式时要特别注意这一点。
(3)如果对观察者的通知是通过另外的线程进行异步投递的话,系统必须保证投递是以自恰的方式进行的。
(4)虽然观察者模式可以随时使观察者知道所观察的对象发生了变化,但是观察者模式没有相应的机制使观察者知道所观察的对象是怎么发生变化的。
观察者模式的实际应用简介:
什么时候使用:
1. 当一个对象的改变需要同时改变其他对象, 而且它不知道具体有多少对象有待改变时, 应该考虑使用观察者模式;
2. 一个抽象模型有两个方面, 其中一个方面依赖于另一方面, 这时用观察者模式可以将这两者封闭在独立的对象中使它们各自独立地改变和复用;
3. 观察者模式所做的工作其实就是在解除耦合. 让耦合的双方都依赖于抽象, 而不是依赖于具体. 从而使得各自的变化都不会影响另一边的变化.
温馨提示:
从具体主题角色指向抽象观察者角色的合成关系,代表具体主题对象可以有任意多个对抽象观察者对象的引用。之所以使用抽象观察者而不是具体观察者,意味着主题对象不需要知道引用了哪些ConcreteObserver类型,而只知道抽象Observer类型。这就使得具体主题对象可以动态地维护一系列的对观察者对象的引用,并在需要的时候调用每一个观察者共有的Update()方法。这种做法叫做"针对抽象编程"。
观察者模式美中不足的地方在于:当一个被观察者对象有很多观察者的时候,通知所有的观察者会消耗很多时间。此时就要求我们根据各种因素进行合理的权衡。