观察者模型课件_第1页
观察者模型课件_第2页
观察者模型课件_第3页
观察者模型课件_第4页
观察者模型课件_第5页
已阅读5页,还剩57页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Observer<观察者>模式

Observer<观察者>模式1

从生活中走进观察者模式在日常生活中,常常会有这样的情形:当某件事情发生时,就应该通知所有的相关者。例如,如果我们的课程改变了时间和地点,就应该通知所有选了这门课程的同学。在软件设计中,也有类似的问题:当一个对象的状态发生变化时,如何能够通知与其相关的所有其他对象,而不用修改该对象的代码?

2

初析观察者模型

在许多设计中,经常涉及到多个对象都对一个特殊对象中的数据变化感兴趣,而且这多个对象都希望跟踪那个特殊对象中的数据变化。例如:求职中心与求职者

3

观察者模型的定义

1、定义对象间的一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都得到通知并被自动更新。

2、别名:依赖(Dependents);发布-订阅(Publish-Subscribe)。ObserverPattern(AnotherName:Dependents,Publish-Subscribe)Defineaone-to-manydependencybetweenobjectssothatwhenoneobjectchangesstate,allitsdependentsarenotifiedandupdatedautomatically.

观察者模型课件4

对概念的加深理解观察者模式中有一个“主题”对象和若干“观察者”对象,主题和观察者之间是一对多的依赖关系。当主题的状态发生变化时,所有观察者都得到通知。例如:求职中心为主题,求职者为观察者

5

观察者模型设计的动机

1、将一个系统分割成一系列相互协作的类有一个常见的副作用:需要维护相关对象的一致性。我们不希望为了维持一致性使各类紧密耦合,因为这样降低了它们的可重用性。

2、观察者模式使得任意数目的观察者不必知道彼此的存在,且主题发生变化时可以得到主题的通知,而同步改变状态。是一种很轻松的耦合。具有很好的可重用性。观察者模6

设计模型的原则

1、将不变部分与固定比便的部分相离。对该原则的理解是:将变化的部分拿来进行封装,以便以后你可以修改它而不会影响那些不变的部分。这一原则几乎是所有设计模式的基础,所有设计模式都提供一种机制:让系统的某些部分独立于其他部分而发生变化。设计模型7

2、对接口编程,而不是对实现编程实现观察者模式的过程:实现观察者模式有很多形式,比较直观的一种是“订阅------通知-----撤销订阅”的形式下。下面我们来详细的描述这一过程:

观察者观察者(observer)将自己注册到被观察对象(subject)中,被观察对象(目标)将观察者存放在一个容器(container)里。2、对接口编程,而不是对实现编程83、被观察对象被观察对象发生了某些变化(如,发行方发行新的报纸),从容器中得到所有注册过的观察者,将变化通知观察者

4、撤销观察观察者告诉被观察者要撤销观察,被观察者从容器中将观察者去除。(观察者将将自己注册到观察者容器时,被观察者不应该过问观察者的具体类型,而是应该使用观察者的接口。这样的优点是:假定程序中还有别的观察者,那么只要这个观察者也是相同的接口实现即可。一个被观察者可以对应多个观察者,当被观察者发生变化的时候,他可以将消息通知所有的观察者。基于接口,而不是具体的实现,这一点位程序提供了更大的灵活性。观察者模型课件9

观察者模式的结构中的角色主题(Subject)观察者(Observer)具体主题(ConcreteSubject)具体观察者(ConcreteObserver)观察者模型课件10

观察者模式里角色的详细解析

1、抽象主题(Subject)角色:主题角色把所有的观察者对象的引用保存在一个列表里;每个主题都可以有任何数量的观察者。主题提供一个接口可以加上或撤销观察者对象;主题角色又叫做抽象被观察者(Observable)角色;

抽象主题角色,有时又叫做抽象被观察者角色,可以用一个抽象类或者一个接口实现;在具体的情况下也不排除使用具体类实现。观察者模式里角色的详细解11

2、抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在得到通知时更新自己;抽象观察者角色,可以用一个抽象类或者一个接口实现;在具体的情况下也不排除使用具体类实现。抽象观察者角色,可以用一个抽象类或者一个接口实现;12

3、具体主题(ConcreteSubject)角色:保存对具体观察者对象有用的内部状态;在这种内部状态改变时给其观察者发出一个通知;具体主题角色又叫作具体被观察者角色;具体主题角色,通常用一个具体子类实现。3、具体主题(ConcreteSubj13

4、具体观察者(ConcreteObserver)角色:保存一个指向具体主题对象的引用;和一个与主题的状态相符的状态。具体观察者角色实现抽象观察者角色所要求的更新自己的接口,以便使本身的状态与主题的状态自恰。具体观察者角色,通常用一个具体子类实现。4、具体观察者(ConcreteObs14呵呵观察者模式类图呵呵观察者模式类图15

举例说明模式的结构的描述与使用例:有一个大学毕业生和一个归国留学者都希望能及时知道求职中心最新的职业需求信息。1.主题:

Subject.javapublicinterfaceSubject{//定义接口

publicvoidaddObserver(Observero);//接口方法1publicvoiddeleteObserver(Observero);//接口方法2publicvoidnotifyObservers();//接口方法3}

162.观察者:

Obsever.javapublicinterfaceObserver{//定义接口观察者publicvoidhearTelephone(StringheardMess);//接口方法}hearTelephone()用来更新数据2.观察者:Obsever.java173.具体主题

SeekJobCenter.javaimportjava.util.ArrayList;publicclassSeekJobCenterimplementsSubject{//实现接口Stringmess;booleanchanged;//定义bool型变量ArrayList<Observer>personList;//定义数组列表

SeekJobCenter(){//方法,找工作中心personList=newArrayList<Observer>();//实例一个数组列表mess=“”;//信息初始值为空changed=false;}3.具体主题SeekJobCenter.java18publicvoidaddObserver(Observero){if(!(personList.contains(o)))//若列表中不包含对象,personList.add(o);//则向列表增加该对象

}publicvoiddeleteObserver(Observero){if(personList.contains(o))//若列表中包含该对象,personList.remove(o);//则从列表移出该对象}publicvoidaddObserver(Observ19publicvoidnotifyObservers(){//方法,信息公示if(changed){//若信息改变for(inti=0;i<personList.size();i++){//则遍历数组列表Observerobserver=personList.get(i);observer.hearTelephone(mess);}//更新列表changed=false;}}publicvoidgiveNewMess(Stringstr){//方法if(str.equals(mess))//检测两个对象(信息)是否相同changed=false;//若相同,则将changed置为false,即信息else{mess=str;//未改变;反之,则将changed置为true,changed=true;}//即信息改变

}}publicvoidnotifyObservers(){204.具体观察者_1UniversityStudent.javaimportjava.io.*;publicclassUniverStudentimplementsObserver{//实现接口,本科生类Subjectsubject;FilemyFile;UniverStudent(Subjectsubject,StringfileName){this.subject=subject;subject.addObserver(this);//使当前实例成为subject所引用的具体主题的观察者

myFile=newFile(fileName);//读取文件名}publicvoidhearTelephone(StringheardMess){//实现方法try{RandomAccessFileout=newRandomAccessFile(myFile,"rw");out.seek(out.length());byte[]b=heardMess.getBytes();out.write(b);//更新文件中的内容

System.out.print("我是一个大学生,");System.out.println("我向文件"+myFile.getName()+"写入如下内容:");System.out.println(heardMess);}catch(IOExceptionexp){System.out.println(exp.toString());}}}4.具体观察者_1UniversityStudent.j215.应用Application.javapublicclassApplication{publicstaticvoidmain(Stringargs[]){//主函数SeekJobCentercenter=newSeekJobCenter();//实例一个对象,找工作中心UniverStudentzhangLin=newUniverStudent(center,“A.txt”);//实例一个对象,本科生HaiGuiwangHao=newHaiGui(center,“B.txt”);//实例一个对象,海归

center.giveNewMess(“腾辉公司需要10个java程序员。”);/

/添加新信息center.notifyObservers();//

公示信息center.giveNewMess("海景公司需要8个动画设计师。");center.notifyObservers();center.giveNewMess("仁海公司需要9个电工。");center.notifyObservers();center.giveNewMess("仁海公司需要9个电工。");center.notifyObservers();}5.应用Application.java22运行结果运行结果23

观察者模式的优点

1、具体主题和具体观察者是松耦合关系。由于主题(Subject)接口仅仅依赖于观察者(Observer)接口,因此具体主题只是知道它的观察者是实现观察者(Observer)接口的某个类的实例,但不需要知道具体是哪个类。同样,由于观察者仅仅依赖于主题(Subject)接口,因此具体观察者只是知道它依赖的主题是实现主题(subject)接口的某个类的实例,但不需要知道具体是哪个类。观察者模式的优点

1、具体主题和具体242、观察模式满足“开-闭原则”。主题(Subject)接口仅仅依赖于观察者(Observer)接口,这样,我们就可以让创建具体主题的类也仅仅是依赖于观察者(Observer)接口,因此如果增加新的实现观察者(Observer)接口的类,不必修改创建具体主题的类的代码。同样,创建具体观察者的类仅仅依赖于主题(Observer)接口,如果增加新的实现主题(Subject)接口的类,也不必修改创建具体观察者类的代码。2、观察模式满足“开-闭原则”。主题(Subject)接口仅25

观察者模式的缺点1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。

2、如果在被观察者之间有循环依赖的话,被观察者会触发它们之间进行循环调用,导致系统崩溃。在使用观察者模式是要特别注意这一点。

3、如果对观察者的通知是通过另外的线程进行异步投递的话,系统必须保证投递是以自恰的方式进行的。

4、虽然观察者模式可以随时使观察者知道所观察的对象发生了变化,但是观察者模式没有相应的机制使观察者知道所观察的对象是怎么发生变化的。

观察者模式的缺点26

观察者模式与其他模式的关系1、观察者模式与备忘录模式的关系观察者模式使用了备忘录模式(MementoPattern),暂时将观察者对象存储在被观察者对象里面观察者模式与MVC模式的关系 观察者模式可以用来实现MVC模式。观察者模式中的主题便是MVC模式中的模型加控制器,而观察者便是视图 一般情况下,MVC是观察者模式、组合模式、策略模式等设计模式的组合。观察者模式与其他模式的关系27

回顾观察者模型下面我们来讨论一个生活中实际问题场景:我和妹妹跟妈妈说:“妈妈,我和妹妹在院子里玩;饭做好了叫我们一声。”请问这是什么模式?能否给出类图说明?

28问题的解析:这是观察者模式。我和妹妹让妈妈告诉我们饭做好了,这样我们就可以来吃饭了。换用较为技术化的语言来说,当系统的主题(饭)发生变化时,就告诉系统的其它部份(观察者们,也就是妈妈、我和妹妹),使其可以调整内部状态(有开始吃饭的准备),并采取相应的行动(吃饭)。问题的解析:29图11、系统的类图。系统的类图说明如下。图11、系统的类图。系统的类图说明如下。30

以上是我们对观察模型的理解

谢谢!!!

以上是我们对观察模型的理解31Observer<观察者>模式

Observer<观察者>模式32

从生活中走进观察者模式在日常生活中,常常会有这样的情形:当某件事情发生时,就应该通知所有的相关者。例如,如果我们的课程改变了时间和地点,就应该通知所有选了这门课程的同学。在软件设计中,也有类似的问题:当一个对象的状态发生变化时,如何能够通知与其相关的所有其他对象,而不用修改该对象的代码?

33

初析观察者模型

在许多设计中,经常涉及到多个对象都对一个特殊对象中的数据变化感兴趣,而且这多个对象都希望跟踪那个特殊对象中的数据变化。例如:求职中心与求职者

34

观察者模型的定义

1、定义对象间的一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都得到通知并被自动更新。

2、别名:依赖(Dependents);发布-订阅(Publish-Subscribe)。ObserverPattern(AnotherName:Dependents,Publish-Subscribe)Defineaone-to-manydependencybetweenobjectssothatwhenoneobjectchangesstate,allitsdependentsarenotifiedandupdatedautomatically.

观察者模型课件35

对概念的加深理解观察者模式中有一个“主题”对象和若干“观察者”对象,主题和观察者之间是一对多的依赖关系。当主题的状态发生变化时,所有观察者都得到通知。例如:求职中心为主题,求职者为观察者

36

观察者模型设计的动机

1、将一个系统分割成一系列相互协作的类有一个常见的副作用:需要维护相关对象的一致性。我们不希望为了维持一致性使各类紧密耦合,因为这样降低了它们的可重用性。

2、观察者模式使得任意数目的观察者不必知道彼此的存在,且主题发生变化时可以得到主题的通知,而同步改变状态。是一种很轻松的耦合。具有很好的可重用性。观察者模37

设计模型的原则

1、将不变部分与固定比便的部分相离。对该原则的理解是:将变化的部分拿来进行封装,以便以后你可以修改它而不会影响那些不变的部分。这一原则几乎是所有设计模式的基础,所有设计模式都提供一种机制:让系统的某些部分独立于其他部分而发生变化。设计模型38

2、对接口编程,而不是对实现编程实现观察者模式的过程:实现观察者模式有很多形式,比较直观的一种是“订阅------通知-----撤销订阅”的形式下。下面我们来详细的描述这一过程:

观察者观察者(observer)将自己注册到被观察对象(subject)中,被观察对象(目标)将观察者存放在一个容器(container)里。2、对接口编程,而不是对实现编程393、被观察对象被观察对象发生了某些变化(如,发行方发行新的报纸),从容器中得到所有注册过的观察者,将变化通知观察者

4、撤销观察观察者告诉被观察者要撤销观察,被观察者从容器中将观察者去除。(观察者将将自己注册到观察者容器时,被观察者不应该过问观察者的具体类型,而是应该使用观察者的接口。这样的优点是:假定程序中还有别的观察者,那么只要这个观察者也是相同的接口实现即可。一个被观察者可以对应多个观察者,当被观察者发生变化的时候,他可以将消息通知所有的观察者。基于接口,而不是具体的实现,这一点位程序提供了更大的灵活性。观察者模型课件40

观察者模式的结构中的角色主题(Subject)观察者(Observer)具体主题(ConcreteSubject)具体观察者(ConcreteObserver)观察者模型课件41

观察者模式里角色的详细解析

1、抽象主题(Subject)角色:主题角色把所有的观察者对象的引用保存在一个列表里;每个主题都可以有任何数量的观察者。主题提供一个接口可以加上或撤销观察者对象;主题角色又叫做抽象被观察者(Observable)角色;

抽象主题角色,有时又叫做抽象被观察者角色,可以用一个抽象类或者一个接口实现;在具体的情况下也不排除使用具体类实现。观察者模式里角色的详细解42

2、抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在得到通知时更新自己;抽象观察者角色,可以用一个抽象类或者一个接口实现;在具体的情况下也不排除使用具体类实现。抽象观察者角色,可以用一个抽象类或者一个接口实现;43

3、具体主题(ConcreteSubject)角色:保存对具体观察者对象有用的内部状态;在这种内部状态改变时给其观察者发出一个通知;具体主题角色又叫作具体被观察者角色;具体主题角色,通常用一个具体子类实现。3、具体主题(ConcreteSubj44

4、具体观察者(ConcreteObserver)角色:保存一个指向具体主题对象的引用;和一个与主题的状态相符的状态。具体观察者角色实现抽象观察者角色所要求的更新自己的接口,以便使本身的状态与主题的状态自恰。具体观察者角色,通常用一个具体子类实现。4、具体观察者(ConcreteObs45呵呵观察者模式类图呵呵观察者模式类图46

举例说明模式的结构的描述与使用例:有一个大学毕业生和一个归国留学者都希望能及时知道求职中心最新的职业需求信息。1.主题:

Subject.javapublicinterfaceSubject{//定义接口

publicvoidaddObserver(Observero);//接口方法1publicvoiddeleteObserver(Observero);//接口方法2publicvoidnotifyObservers();//接口方法3}

472.观察者:

Obsever.javapublicinterfaceObserver{//定义接口观察者publicvoidhearTelephone(StringheardMess);//接口方法}hearTelephone()用来更新数据2.观察者:Obsever.java483.具体主题

SeekJobCenter.javaimportjava.util.ArrayList;publicclassSeekJobCenterimplementsSubject{//实现接口Stringmess;booleanchanged;//定义bool型变量ArrayList<Observer>personList;//定义数组列表

SeekJobCenter(){//方法,找工作中心personList=newArrayList<Observer>();//实例一个数组列表mess=“”;//信息初始值为空changed=false;}3.具体主题SeekJobCenter.java49publicvoidaddObserver(Observero){if(!(personList.contains(o)))//若列表中不包含对象,personList.add(o);//则向列表增加该对象

}publicvoiddeleteObserver(Observero){if(personList.contains(o))//若列表中包含该对象,personList.remove(o);//则从列表移出该对象}publicvoidaddObserver(Observ50publicvoidnotifyObservers(){//方法,信息公示if(changed){//若信息改变for(inti=0;i<personList.size();i++){//则遍历数组列表Observerobserver=personList.get(i);observer.hearTelephone(mess);}//更新列表changed=false;}}publicvoidgiveNewMess(Stringstr){//方法if(str.equals(mess))//检测两个对象(信息)是否相同changed=false;//若相同,则将changed置为false,即信息else{mess=str;//未改变;反之,则将changed置为true,changed=true;}//即信息改变

}}publicvoidnotifyObservers(){514.具体观察者_1UniversityStudent.javaimportjava.io.*;publicclassUniverStudentimplementsObserver{//实现接口,本科生类Subjectsubject;FilemyFile;UniverStudent(Subjectsubject,StringfileName){this.subject=subject;subject.addObserver(this);//使当前实例成为subject所引用的具体主题的观察者

myFile=newFile(fileName);//读取文件名}publicvoidhearTelephone(StringheardMess){//实现方法try{RandomAccessFileout=newRandomAccessFile(myFile,"rw");out.seek(out.length());byte[]b=heardMess.getBytes();out.write(b);//更新文件中的内容

System.out.print("我是一个大学生,");System.out.println("我向文件"+myFile.getName()+"写入如下内容:");System.out.println(heardMess);}catch(IOExceptionexp){System.out.println(exp.toString());}}}4.具体观察者_1UniversityStudent.j525.应用Application.javapublicclassApplication{publicstaticvoidmain(Stringargs[]){//主函数SeekJobCentercenter=newSeekJobCenter();//实例一个对象,找工作中心UniverStudentzhangLin=newUniverStudent(center,“A.txt”);//实例一个对象,本科生HaiGuiwangHao=newHaiGui(center,“B.txt”);//实例一个对象,海归

center.giveNewMess(“腾辉公司需要10个java程序员。”);/

/添加新信息center.notifyObservers();//

公示信息center.giveNewMess("海景公司需要8个动画设计师。");center.notifyObservers();center.giveNewMess("仁海公司需要9个电工。");center.notifyObservers();center.giveNewMess("仁海公司需要9个电工。");center.notifyObservers();

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论