软件体系结构与设计模式 观察者模式

上传人:fgh****35 文档编号:172625837 上传时间:2022-12-05 格式:DOC 页数:11 大小:141.50KB
返回 下载 相关 举报
软件体系结构与设计模式 观察者模式_第1页
第1页 / 共11页
软件体系结构与设计模式 观察者模式_第2页
第2页 / 共11页
软件体系结构与设计模式 观察者模式_第3页
第3页 / 共11页
点击查看更多>>
资源描述
观察者模式(别名:依赖,发布-订阅) 定义对象间的一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都得到通知并被自动更新。 Observer Pattern(Another Name: Dependents, Publish-Subscribe) Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. 一、概述在许多设计中,经常涉及到多个对象都对一个特殊对象中的数据变化感兴趣,而且这多个对象都希望跟踪那个特殊对象中的数据变化。二、 模式的结构与使用 观察者模式的结构中包括四种角色: 主题(Subject) 观察者(Observer) 具体主题(ConcreteSubject) 具体观察者(ConcreteObserver) 模式的结构的描述与使用有一个大学毕业生和一个归国留者都希望能及时知道“求职中心”最新的职业需求信息。1主题 : Subject.java public interface Subject public void addObserver(Observer o); public void deleteObserver(Observer o); public void notifyObservers();主题接口规定了具体主题需要实现的添加、删除观察者以及通知观察者更新数据的方法2观察者 : Obsever.java public interface Observer public void hearTelephone(String heardMess); 观察者接口规定了具体观察者用来更新数据的方法。3具体主题 SeekJobCenter.java_1 public class SeekJobCenter implements Subject String mess; boolean changed; ArrayList personList; SeekJobCenter() personList=new ArrayList(); mess=; changed=false; public void addObserver(Observer o) if(!(personList.contains(o) personList.add(o); public void deleteObserver(Observer o) if(personList.contains(o) personList.remove(o); 3具体主题 SeekJobCenter.java_2 public void notifyObservers() if(changed) for(int i=0;ipersonList.size();i+) Observer observer=personList.get(i); observer.hearTelephone(mess); changed=false; public void giveNewMess(String str) if(str.equals(mess) changed=false; else mess=str; changed=true; 具体主题通过实现notifyObservers()方法来通知具体观察者,实现的方式是遍历具体主题中用来存放观察者引用的集合,并让集合中的每个具体观察者执行观察者接口规定更新数据的方法。4具体观察者_1 UniversityStudent.java public class UniverStudent implements Observer Subject subject; File myFile; UniverStudent(Subject subject,String fileName) this.subject=subject; subject.addObserver(this); myFile=new File(fileName); public void hearTelephone(String heardMess) try RandomAccessFile out=new RandomAccessFile(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(IOException exp)System.out.println(exp.toString(); 4具体观察者_2 HaiGui.java public class HaiGui implements Observer Subject subject; File myFile; HaiGui(Subject subject,String fileName) this.subject=subject; subject.addObserver(this); myFile=new File(fileName); public void hearTelephone(String heardMess) try boolean boo=heardMess.contains(java程序员); if(boo) RandomAccessFile out=new RandomAccessFile(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); else System.out.println(我是海归,这次的信息中没有我需要的信息); catch(IOException exp)System.out.println(exp.toString(); 5应用 Application.javapublic class Application public static void main(String args) SeekJobCenter center=new SeekJobCenter(); UniverStudent zhangLin=new UniverStudent(center,A.txt); HaiGui wangHao=new HaiGui(center,B.txt); center.giveNewMess(腾辉公司需要10个java程序员。); center.notifyObservers(); center.giveNewMess(海景公司需要8个动画设计师。); center.notifyObservers(); center.giveNewMess(仁海公司需要9个电工。); center.notifyObservers(); center.giveNewMess(仁海公司需要9个电工。); center.notifyObservers(); 三、“推”数据与“拉”数据 推数据方式是指具体主题将变化后的数据全部交给具体观察者。 具体主题认为具体观察者需要这些变化后的全部数据 拉数据方式是指具体主体提供了获得变化后数据的方法,具体观察者调用这些方法获得变化后的数据。 具体主题不知道具体观察者是否需要这些变化后的数据行为协作四、观察者模式的优点 具体主题和具体观察者是松耦合关系。由于主题(Subject)接口仅仅依赖于观察者(Observer)接口,因此具体主题只是知道它的观察者是实现观察者(Observer)接口的某个类的实例,但不需要知道具体是哪个类。同样,由于观察者仅仅依赖于主题(Subject)接口,因此具体观察者只是知道它依赖的主题是实现主题(subject)接口的某个类的实例,但不需要知道具体是哪个类。 观察模式满足“开-闭原则”。主题(Subject)接口仅仅依赖于观察者(Observer)接口,这样,我们就可以让创建具体主题的类也仅仅是依赖于观察者(Observer)接口,因此如果增加新的实现观察者(Observer)接口的类,不必修改创建具体主题的类的代码。同样,创建具体观察者的类仅仅依赖于主题(Observer)接口,如果增加新的实现主题(Subject)接口的类,也不必修改创建具体观察者类的代码。五、应用举例 老师有电话号码,学生需要知道老师的电话号码以便于在合时的时候拨打,在这样的组合中,老师就是一个被观察者(Subject),学生就是需要知道信息的观察者,当老师的电话号码发生改变时,学生得到通知,并更新相应的电话记录 public interface Subjectpublic void attach(Observer o);public void detach(Observer o);public void notice();package observer;public interface 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.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;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(); 第七章 策略模式策略模式(别名:政策) 定义一系列算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。Strategy Pattern(Another Name: Policy) Define a family of algorithms, encapsulate each one, and make them inter changeable. Strategy lets the algorithm vary independently from clients that use it. 一 、 概述 策略模式是处理算法的不同变体的一种成熟模式,策略模式通过接口或抽象类封装算法的标识,即在接口中定义一个抽象方法,实现该接口的类将实现接口中的抽象方法。 在策略模式中,封装算法标识的接口称作策略,实现该接口的类称作具体二、策略模式的结构与使用 策略模式的结构中包括三种角色: 策略(Strategy) 具体策略(ConcreteStrategy) 上下文(Context) 策略模式的UML类图 策略模式的结构的描述与使用 在某种比赛中有若干个裁判,每位裁判给选手一个得分。选手的最后得分是根据全体裁判的得分计算出来的。请给出几种计算选手得分的评分方案,对于某次比赛,可以从你的方案中选择一种方案作为本次比赛的评分方案。 1策略(Strategy) : Computable.java public interface ComputableStrategy public abstract double computeScore(double a); 2具体策略(ConcreteStrategy): StrategyOne.java (代数平均值方法)public class StrategyOne implements ComputableStrategy public double computeScore(double a) double score=0,sum=0; for(int i=0;ia.length;i+) sum=sum+ai; score=sum/a.length; return score; 2具体策略(ConcreteStrategy): StrategyTwo.java (去掉最大值和最小值,然后计算代数平均值)import java.util.Arrays;public class StrategyTwo implements ComputableStrategy public double computeScore(double a) if(a.length=2) return 0; double score=0,sum=0; Arrays.sort(a); for(int i=1;ia.length-1;i+) sum=sum+ai; score=sum/(a.length-2); return score; 3上下文: GymnasticsGame.java public class GymnasticsGame ComputableStrategy strategy; public void setStrategy(ComputableStrategy strategy) this.strategy=strategy; public double getPersonScore(double a) if(strategy!=null) return puteScore(a); else return 0; 4应用: Application.java_1 public class Application public static void main(String args) GymnasticsGame game=new GymnasticsGame(); game.setStrategy(new StrategyOne(); Person zhang=new Person(); zhang.setName(张三); double a=9.12,9.25,8.87,9.99,6.99,7.88; Person li=new Person(); li.setName(李四); double b=9.15,9.26,8.97,9.89,6.97,7.89; zhang.setScore(game.getPersonScore(a); li.setScore(game.getPersonScore(b); System.out.println(使用算术平均值方案:); System.out.println(得分:,zhang.getName(),zhang.getScore(); System.out.println(得分:%5.3f%n,li.getName(),li.getScore();4应用: Application.java_2class Person String name; double score; public void setScore(double t) score=t; public void setName(String s) name=s; public double getScore() return score; public String getName() return name; 三、策略模式的优点 上下文(Context)和具体策略(ConcreteStrategy)是松耦合关系。因此上下文只知道它要使用某一个实现Strategy接口类的实例,但不需要知道具体是哪一个类。 策略模式满足“开-闭原则”。当增加新的具体策略时,不需要修改上下文类的代码,上下文就可以引用新的具体策略的实例。 四、适合使用策略模式的情景 一个类定义了多种行为,并且这些行为在这个类中以多个条件语句的形式出现,可以使用策略模式避免在类中使用大量的条件语句。 程序不需要暴露复杂的、与算法相关的数据结构,可以使用策略模式封装算法。 需要使用一个算法的不同变体。 把数组导出为表格的算法,输入一个数组,导出一个表格,当用户想改变导出的表格时,便可以通过改变输出的算法改变输出的结果。如果输出的内容用以网页显示,则输出JackMayaMikesShadow 如果输出的结果用以直接的屏幕输出,则可以输出: +-+-+-+-+ |Jack|Maya|Mikes|Shadow| +-+-+-+-+public interface TableExporterpublic String getExported(String data);public class HtmlExporter implements TableExporterpublic String getExported(String data)if(data = null)return ;StringBuffer sb = new StringBuffer();sb.append();for(int i=0;idata.length;i+)sb.append(+datai+);sb.append();return sb.toString();public class LineExporter implements TableExporterpublic String getExported(String data)if(data = null)return ;StringBuffer top = new StringBuffer(+);StringBuffer mid = new StringBuffer(|);for(int i =0;idata.length;i+)String str = datai;for(int j=0;jstr.length();j+)top.append(-);mid.append(str);top.append(+);mid.append(|);top.append(n);mid.append(n);return top.toString()+mid.toString()+top.toString();public class Clientpublic static void main(String args)String data = new StringJack,Maya,Mikes,Shadow;TableExporter tb;tb = new HtmlExporter();System.out.println(tb.getExported(data);tb = new LineExporter();System.out.println(tb.getExported(data);
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 商业管理 > 营销创新


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!