android,【原创·教程·连载】《Android之大话设计模式》--设计模式之行为型模式 第十五章:观察者模式 GG在MM身边有两个妹妹

<大话设计模式>

本教程说明及版权声明

国士工作室是一支专注于Android平台企业级应用开发的技术团队,致力于做中国最棒的Android应用程序开发机构,提供最棒的Android企业级应用开发培训服务。
企业培训和开发合作官方联系方式:
电话:18610086859
Email:[email protected]
QQ:1740415547
QQ群:148325348
国士工作室 有你更美好!
l 该文档参考和使用了网络上的免费开放的图片和内容,并以免费开放的方式发布,希望为移动互联网和智能手机时代贡献绵薄之力!可以随意转载,但不得使用该文档谋利。
l 如果对该文档有任何疑问或者建议,请进入官方博客
http://www.cnblogs.com/guoshiandroid/留言或者直接与国士工作室联系(后附联系方式),我们会慎重参考您的建议并根据需要对本文档进行修改,以造福更多开发者!
l 《大话设计模式》的最新及完整内容会在国士工作室官方博客定期更新,请访问国士工作室博客
http://www.cnblogs.com/guoshiandroid/获取更多更新内容。
观察者模式 GGMM身边有两个妹妹

观察者模式应用场景举例
GG每天晚上临睡前都要查考一个邮件组,这个邮件组主要是GG和MM的两个密友(这两个女生都是GG的妹妹)建立的,两个妹妹把MM需要人帮助和需要体贴的地方发到发送到邮箱,这个时候GG就可以每天在MM需要的时候都挺身而出,说:“有我在!不要怕!”。GG每次打开这个邮件组的时候都很激动,心里还总是宁愿MM有事情,这样GG就可以表现自己啦^_^

观察者模式解释:
观察者模式(Observer Pattern)又名发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式、从属者(Dependents)模式,观察者模式定义了定义了一种对象间的一种一对多的依赖关系,当一个对象的状态发生变化的时候,所有依赖于它的对象都得到通知并且被自动刷新对象状态。
观察模式提供给关联对象的一种同步通信的手段,使得某个对象和依赖它的对象之间保持状态的同步。
英文定义为:Define a _disibledevent=>。
观察者模式的UML图:
观察者模式所涉及的角色如下:
抽象被观察者(Subject):被观察的对象,当需要被观察的状态发生改变时,被观察者需要通知队列中的所有观察者对象。Subject可以有任意多个观察者对象,被观察者需要维持一个观察者对象的队列列表,通过这种维持是指添加、删除、通知被观察者。
具体被观察者(ConcreteSubject):被观察者的具体的实现。包含一些基本的属性及其他操作。
抽象观察者(Observer):是一个接口或者抽象类。当被观察者的状态发生改变时,观察者对象将通过一个回调函数得到通知。
具体观察者(ConcreteObserver):观察者的具体实现。存储有关的状态,这些状态应与被观察者的状态保持一致。实现Observer的更新接口以使得自身状态和目标的状态保持一致。在本角色内也可以维护一个指向具体的被观察者对象的引用。
观察者模式的UML图如下 所示:
【原创&#183;教程&#183;连载】《Android之大话设计模式》--设计模式之行为型模式 第十五章:观察者模式 GG在MM身边有两个妹妹android


观察者模式深入分析
观察者模式(Observer)完美的将观察者和被观察的对象分离开。举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。面向对象设计的一个原则是:系统中的每个类将重点放在某一个功能上,而不是其他方面。一个对象只做一件事情,并且将他做好。观察者模式在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。
观察者模式有很多实现方式,从根本上说,该模式必须包含两个角色:观察者和被观察对象。在刚才的例子中,业务数据是被观察对象,用户界面是观察者。观察者和被观察者之间存在“观察”的逻辑关联,当被观察者发生改变的时候,观察者就会观察到这样的变化,并且做出相应的响应。如果在用户界面、业务数据之间使用这样的观察过程,可以确保界面和数据之间划清界限,假定应用程序的需求发生变化,需要修改界面的表现,只需要重新构建一个用户界面,业务数据不需要发生变化。
“观察”不是“直接调用”
实现观察者模式的时候要注意,观察者和被观察对象之间的互动关系不能体现成类之间的直接调用,否则就将使观察者和被观察对象之间紧密的耦合起来,从根本上违反面向对象的设计的原则。无论是观察者“观察”观察对象,还是被观察者将自己的改变“通知”观察者,都不应该直接调用。
实现观察者模式有很多形式,比较直观的一种是使用一种“注册——通知——撤销注册”的形式。下面的三个图详细的描述了这样一种过程:
1:观察者(Observer)将自己注册到被观察对象(Subject)中,被观察对象将观察者存放在一个容器(Container)里。
2:被观察对象发生了某种变化(如图中的SomeChange),从容器中得到所有注册过的观察者,将变化通知观察者。
3:观察者告诉被观察者要撤销观察,被观察者从容器中将观察者去除。
观察者将自己注册到被观察者的容器中时,被观察者不应该过问观察者的具体类型,而是应该使用观察者的接口。这样的优点是:假定程序中还有别的观察者,那么只要这个观察者也是相同的接口实现即可。一个被观察者可以对应多个观察者,当被观察者发生变化的时候,他可以将消息一一通知给所有的观察者。基于接口,而不是具体的实现——这一点为程序提供了更大的灵活性。
观察者模式使用场景分析及代码实现:
在上面的使用场景中,MM是被观察者,GG是观察者图如下所示:
【原创&#183;教程&#183;连载】《Android之大话设计模式》--设计模式之行为型模式 第十五章:观察者模式 GG在MM身边有两个妹妹android
建立一个实体类:
package com.diermeng.designPattern.Observer.impl;
/*
* MM的困难或者事件记录器
*/
public class Event {
//事件标题
private String title;
//事件内容
private String content;

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public String getContent() {
return content;
}

public void setContent(String content) {
this.content = content;
}

}



建立GG这个具体观察者:
package com.diermeng.designPattern.Observer.impl;

import java.util.Observable;
import java.util.Observer;
/*
* GG作为MM的观察者 实现了Oberver接口
*/
public class GG implements Observer {
/*
* 覆写update方法 实现GG自己的业务方法
* @see java.util.Observer#update(java.util.Observable, java.lang.Object)
*/
public void update(Observable o, Object arg) {
Event art = (Event)arg;

System.out.println("MM有新情况了,快来看吧!");
System.out.println("情况标题为:" + art.getTitle());
System.out.println("情况内容为:" + art.getContent());
}

}

建立MM这个具体被观察者:
package com.diermeng.designPattern.Observer.impl;

import java.util.Observable;
/*
* MM作为被观察者 继承了Observable类
*/
public class MM extends Observable {

public void publishEvent(String title,String cotent) {
Event art = new Event();
art.setTitle(title);
art.setContent(cotent);
System.out.println("MM有新情况了,标题:" + title + ",内容:" + cotent);
this.setChanged();
this.notifyObservers(art);
}
}



建立一个测试客户端:
package com.diermeng.designPattern.Observer.client;

import com.diermeng.designPattern.Observer.impl.GG;
import com.diermeng.designPattern.Observer.impl.MM;
/*
* 观察者模式测试客户端
*/
public class ObserverTest {
public static void main(String[] args) {
MM user = new MM();
user.addObserver(new GG());
user.publishEvent("我有新情况啦", "Oh My God,我有新情况啦,Help!!!");
}
}


运行结果如下:
MM有新情况了,标题:我有新情况啦,内容:Oh My God,我有新情况啦,Help!!!
MM有新情况了,快来看吧!
情况标题为:我有新情况啦
情况内容为:Oh My God,我有新情况啦,Help!!!



观察者模式的优缺点分析:
Observer模式的优点是实现了表示层和数据逻辑层的分离,并定义了稳定的更新消息传递机制,类别清晰,并抽象了更新接口,使得可以有各种各样不同的表示层(观察者)。但是其缺点是每个外观对象必须继承这个抽像出来的接口类,这样就造成了一些不方便,比如有一个别人写的外观对象,并没有继承该抽象类,或者接口不对,我们又希望不修改该类直接使用它。虽然可以再应用Adapter模式来一定程度上解决这个问题,但是会造成更加复杂烦琐的设计,增加出错几率。
观察者模式的效果有以下几个优点:
(1)观察者模式在被观察者和观察者之间建立一个抽象的耦合。被观察者角色所知道的只是一个具体现察者聚集,每一个具体现察者都符合一个抽象观察者的接口。被观察者并不认识任何一个具体观察者,它只知道它们都有一个共同的接口。由于被观察者和观察者没有紧密地耦合在一起,因此它们可以属于不同的抽象化层次。
(2)观察者模式支持广播通信。被观察者会向所有的登记过的观察者发出通知。
观察者模式有下面的一些缺点:
(1)如果一个被观察者对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
(2)如果在被观察者之间有循环依赖的话,被观察者会触发它们之间进行循环调用,导致系统崩溃。在使用观察考模式时要特别注意这一点。
(3)如果对观察者的通知是通过另外的线程进行异步投递的话,系统必须保证投递是以自恰的方式进行的。
(4)虽然观察者模式可以随时使观察者知道所观察的对象发生了变化,但是观察者模式没有相应的机制使观察者知道所观察的对象是怎么发生变化的。
观察者模式的实际应用简介:
什么时候使用:
1. 当一个对象的改变需要同时改变其他对象, 而且它不知道具体有多少对象有待改变时, 应该考虑使用观察者模式;
2. 一个抽象模型有两个方面, 其中一个方面依赖于另一方面, 这时用观察者模式可以将这两者封闭在独立的对象中使它们各自独立地改变和复用;
3. 观察者模式所做的工作其实就是在解除耦合. 让耦合的双方都依赖于抽象, 而不是依赖于具体. 从而使得各自的变化都不会影响另一边的变化.
温馨提示:
从具体主题角色指向抽象观察者角色的合成关系,代表具体主题对象可以有任意多个对抽象观察者对象的引用。之所以使用抽象观察者而不是具体观察者,意味着主题对象不需要知道引用了哪些ConcreteObserver类型,而只知道抽象Observer类型。这就使得具体主题对象可以动态地维护一系列的对观察者对象的引用,并在需要的时候调用每一个观察者共有的Update()方法。这种做法叫做"针对抽象编程"。
观察者模式美中不足的地方在于:当一个被观察者对象有很多观察者的时候,通知所有的观察者会消耗很多时间。此时就要求我们根据各种因素进行合理的权衡。

Tags: 

延伸阅读

最新评论

发表评论