《软件体系结构与设计模式 第六章 观察者模式.ppt》由会员分享,可在线阅读,更多相关《软件体系结构与设计模式 第六章 观察者模式.ppt(23页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第六章第六章 观察者模式观察者模式 1/6/20231观察者模式(别名:依赖,发布观察者模式(别名:依赖,发布-订阅)订阅)定定义义对对象象间间的的一一种种一一对对多多的的依依赖赖关关系系,当当一一个个对对象象的的状状态态发发生生变变化化时时,所所有有依依赖赖于于它它的的对对象象都都得得到到通通知知并并被被自动更新。自动更新。Observer Pattern(Another Name:Dependents,Publish-Subscribe)Define a one-to-many dependency between objects so that when one object chang
2、es state,all its dependents are notified and updated automatically.一一、概述概述 1/6/20232 在许多设计中,经常涉及到多个对象在许多设计中,经常涉及到多个对象都对一个特殊对象中的数据变化感兴趣,都对一个特殊对象中的数据变化感兴趣,而且这多个对象都希望跟踪那个特殊对而且这多个对象都希望跟踪那个特殊对象中的数据变化。象中的数据变化。二、二、模式的结构与使用模式的结构与使用 1/6/20233观察者模式的结构中包括四种角色:观察者模式的结构中包括四种角色:主题(主题(SubjectSubject)观察者(观察者(Observ
3、erObserver)具体主题(具体主题(ConcreteSubjectConcreteSubject)具体观察者(具体观察者(ConcreteObserverConcreteObserver)1/6/20234模式的模式的UMLUML类图类图 模式的结构的描述与使用模式的结构的描述与使用有一个大学毕业生和一个归国留者都希望能及时知道“求职中心”最新的职业需求信息。1/6/202361 1主题主题 :Subject.java Subject.java public interface Subject public interface Subject public void public voi
4、d addObserver(ObserveraddObserver(Observer o);o);public void public void deleteObserver(ObserverdeleteObserver(Observer o);o);public void public void notifyObserversnotifyObservers();();主题接口规定了具体主题需要实现的添加、删除观察者以及通知观察者更新数据的方法。1/6/202372 2观察者观察者 :Obsever.javaObsever.java public interface Observerpubli
5、c interface Observer public void public void hearTelephone(StringhearTelephone(String heardMessheardMess););观察者接口规定了具体观察者用来更新数据的方法。1/6/202383 3具体主题具体主题 SeekJobCenter.java_1 SeekJobCenter.java_1 public class public class SeekJobCenterSeekJobCenter implements Subject implements Subject String mess;Str
6、ing mess;booleanboolean changed;changed;ArrayListArrayList personListpersonList;SeekJobCenterSeekJobCenter()()personListpersonList=new=new ArrayListArrayList();();mess=;mess=;changed=false;changed=false;public void public void addObserver(ObserveraddObserver(Observer o)o)if(!(personList.contains(oif
7、(!(personList.contains(o)personList.add(opersonList.add(o););public void public void deleteObserver(ObserverdeleteObserver(Observer o)o)if(personList.contains(oif(personList.contains(o)personList.remove(opersonList.remove(o););1/6/202393 3具体主题具体主题 SeekJobCenter.java_2 SeekJobCenter.java_2 public voi
8、d public void notifyObserversnotifyObservers()()if(changedif(changed)for(intfor(int i=0;i i=0;ipersonList.size();ipersonList.size();i+)+)Observer observer=Observer observer=personList.get(ipersonList.get(i););observer.hearTelephone(messobserver.hearTelephone(mess););changed=false;changed=false;publi
9、c void public void giveNewMess(StringgiveNewMess(String strstr)if(str.equals(messif(str.equals(mess)changed=false;changed=false;else else mess=mess=strstr;changed=true;changed=true;具体主题通过实现具体主题通过实现notifyObservers()方法来通知具体观察方法来通知具体观察者,实现的方式是遍历具体主题中用来存放观察者引用的者,实现的方式是遍历具体主题中用来存放观察者引用的集合,并让集合中的每个具体观察者执行
10、观察者接口规定集合,并让集合中的每个具体观察者执行观察者接口规定更新数据的方法。更新数据的方法。1/6/2023114 4具体观察者具体观察者_1 _1 UniversityStudent.javaUniversityStudent.javapublic class public class UniverStudentUniverStudent implements Observer implements Observer Subject subject;Subject subject;File File myFilemyFile;UniverStudent(SubjectUniverStud
11、ent(Subject subject,String subject,String fileNamefileName)this.subject=subject;this.subject=subject;subject.addObserver(thissubject.addObserver(this););myFilemyFile=new=new File(fileNameFile(fileName););public void public void hearTelephone(StringhearTelephone(String heardMessheardMess)try try Rand
12、omAccessFileRandomAccessFile out=new out=new RandomAccessFile(myFile,rwRandomAccessFile(myFile,rw););out.seek(out.length();out.seek(out.length();byte b=byte b=heardMess.getBytesheardMess.getBytes();();out.write(b);out.write(b);System.out.printSystem.out.print(我是一个大学生我是一个大学生,);,);System.out.printlnSy
13、stem.out.println(我我向向文文件件+myFile.getNamemyFile.getName()+()+写写入入如如下内容下内容:);:);System.out.println(heardMessSystem.out.println(heardMess););catch(IOExceptioncatch(IOException exp)System.out.println(exp.toStringexp)System.out.println(exp.toString();();1/6/2023124 4具体观察者具体观察者_2 _2 HaiGui.javaHaiGui.java
14、 public class public class HaiGuiHaiGui implements Observer implements Observer Subject subject;Subject subject;File File myFilemyFile;HaiGui(SubjectHaiGui(Subject subject,String subject,String fileNamefileName)this.subject=subject;this.subject=subject;subject.addObserver(thissubject.addObserver(thi
15、s););myFilemyFile=new=new File(fileNameFile(fileName););public void public void hearTelephone(StringhearTelephone(String heardMessheardMess)try try booleanboolean boo=boo=heardMess.contains(javaheardMess.contains(java程序员程序员););if(boo)if(boo)RandomAccessFileRandomAccessFile out=new out=new RandomAcce
16、ssFile(myFile,rwRandomAccessFile(myFile,rw););out.seek(out.length();out.seek(out.length();byte b=byte b=heardMess.getBytesheardMess.getBytes();();out.write(b);out.write(b);System.out.print(System.out.print(我是一个海归我是一个海归,);,);System.out.printlnSystem.out.println(我我向向文文件件+myFile.getNamemyFile.getName()
17、+()+写写入入如如下下内内容容:);:);System.out.println(heardMessSystem.out.println(heardMess););else else System.out.printlnSystem.out.println(我是海归我是海归,这次的信息中没有我需要的信息这次的信息中没有我需要的信息););catch(IOExceptioncatch(IOException exp)System.out.println(exp.toStringexp)System.out.println(exp.toString();();1/6/2023135 5应用应用 A
18、pplication.javaApplication.javapublic class Applicationpublic class Application public static void main(String public static void main(String argsargs)SeekJobCenterSeekJobCenter center=new center=new SeekJobCenterSeekJobCenter();();UniverStudentUniverStudent zhangLinzhangLin=new=new UniverStudent(ce
19、nter,A.txtUniverStudent(center,A.txt););HaiGuiHaiGui wangHaowangHao=new=new HaiGui(center,B.txtHaiGui(center,B.txt););center.giveNewMesscenter.giveNewMess(腾辉公司需要腾辉公司需要1010个个javajava程序员。程序员。););center.notifyObserverscenter.notifyObservers();();center.giveNewMesscenter.giveNewMess(海景公司需要海景公司需要8 8个动画设计
20、师。个动画设计师。););center.notifyObserverscenter.notifyObservers();();center.giveNewMesscenter.giveNewMess(仁海公司需要仁海公司需要9 9个电工。个电工。););center.notifyObserverscenter.notifyObservers();();center.giveNewMesscenter.giveNewMess(仁海公司需要仁海公司需要9 9个电工。个电工。););center.notifyObserverscenter.notifyObservers();();三、“推”数据与“
21、拉”数据推数据方式是指具体主题将变化后的数据全部交给具体观察者。具体主题认为具体观察者需要这些变化后的全部数据拉数据方式是指具体主体提供了获得变化后数据的方法,具体观察者调用这些方法获得变化后的数据。具体主题不知道具体观察者是否需要这些变化后的数据行为协作四、四、观察者模式的优点观察者模式的优点 1/6/202316具体主题和具体观察者是松耦合关系。由于主题(Subject)接口仅仅依赖于观察者(Observer)接口,因此具体主题只是知道它的观察者是实现观察者(Observer)接口的某个类的实例,但不需要知道具体是哪个类。同样,由于观察者仅仅依赖于主题(Subject)接口,因此具体观察者
22、只是知道它依赖的主题是实现主题(subject)接口的某个类的实例,但不需要知道具体是哪个类。观察模式满足“开-闭原则”。主题(Subject)接口仅仅依赖于观察者(Observer)接口,这样,我们就可以让创建具体主题的类也仅仅是依赖于观察者(Observer)接口,因此如果增加新的实现观察者(Observer)接口的类,不必修改创建具体主题的类的代码。同样,创建具体观察者的类仅仅依赖于主题(Observer)接口,如果增加新的实现主题(Subject)接口的类,也不必修改创建具体观察者类的代码。五、应用举例老师有电话号码,学生需要知道老师的电老师有电话号码,学生需要知道老师的电话号码以便于
23、在合时的时候拨打,在这样话号码以便于在合时的时候拨打,在这样的组合中,老师就是一个被观察者的组合中,老师就是一个被观察者(Subject),学生就是需要知道信息的观),学生就是需要知道信息的观察者,当老师的电话号码发生改变时,学察者,当老师的电话号码发生改变时,学生得到通知,并更新相应的电话记录生得到通知,并更新相应的电话记录 public interface Subjectpublic void attach(Observer o);public void detach(Observer o);public void notice();package observer;public inte
24、rface Observerpublic void update();public class Teacher implements Subjectprivate String phone;private Vector students;public Teacher()phone=;students=new Vector();public void attach(Observer o)students.add(o);public void detach(Observer o)students.remove(o);public void notice()for(int i=0;istudents
25、.size();i+)(Observer)students.get(i).update();public void setPhone(String phone)this.phone=phone;notice();public String getPhone()return phone;public class Student implements Observerprivate String name;private String phone;private Teacher teacher;public Student(String name,Teacher t)this.name=name;
26、teacher=t;public void show()System.out.println(Name:+name+nTeachersphone:+phone);public void update()phone=teacher.getPhone();public class Clientpublic static void main(String args)Vector students=new Vector();Teacher t=new Teacher();for(int i=0;i10;i+)Student st=new Student(lili+i,t);students.add(st);t.attach(st);t.setPhone(88803807);for(int i=0;i10;i+)(Student)students.get(i).show();t.setPhone(88808880);for(int i=0;i10;i+)(Student)students.get(i).show();