1、软件体系结构与设计模式实验报告书实验次序/名称:实验类型:设计型/验证型实验时间:实验地点:学生班级:学号:姓名:指导教师:计算机与通信工程学院实验三:观察者模式实验目的:1、明确观察者模式的概念和应用环境。2、使用 JAVA 语言实现规定案例的观察者模式开发。3、分析观察者模式的特点。实验内容:1、预备知识观察者模式 Observer观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,让它们能够自动更新自己。观察者模式的组成抽象主题角色:把所有对观察者对象的引用保存在一个集合中,每个抽象主题角色都可以有任意数量的
2、观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。抽象观察者角色:为所有具体的观察者定义一个接口,在得到主题的通知时更新自己。具体主题角色:在具体主题内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个子类实现。具体观察者角色:该角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。通常用一个子类实现。如果需要,具体观察者角色可以保存一个指向具体主题角色的引用。Java 的 API 中为我们供给了 Observer 形式的告终。翔实由java.util.Observable 类和 java.util.Observer 接
3、口告知。前者有两个重要的措施:setChanged:设置内部事态为已改换notifyObservers(Object obj):通知考察者所发生的改换,参数 obj 是一些改换的消息后者有一个中心措施:update(Object obj):相应被考察者的改换,其中 obj 即便被考察者递交到来的消息,该措施会在 notifyObservers 被调用时积极调用。2、案例情景:(可任选一个场景设计)场景 1:网上商店中商品在名称、价格等方面有变化,希望系统能自动通知会员。场景 2:房屋价格变动通知给购房者、3、编写 JAVA 代码实现案例要求功能。程序实例提示:通过程序实例来说明观察者模式:首先
4、定义抽象的观察者:/抽象观察者角色public interface Watcherpublic void update(String str);复制代码然后定义抽象的主题角色,即抽象的被观察者,在其中声明方法(添加、移除观察者,通知观察者):复制代码/抽象主题角色,watched:被观察public interface Watchedpublic void addWatcher(Watcher watcher);public void removeWatcher(Watcher watcher);public void notifyWatchers(String str);复制代码然后定义具体
5、的观察者:复制代码public class ConcreteWatcher implements WatcherOverridepublic void update(String str)System.out.println(str);复制代码之后是具体的主题角色: 复制代码import java.util.ArrayList;import java.util.List;public class ConcreteWatched implements Watched/ 存放观察者private List list = new ArrayList();Overridepublic void add
6、Watcher(Watcher watcher)list.add(watcher);Overridepublic void removeWatcher(Watcher watcher)list.remove(watcher);Overridepublic void notifyWatchers(String str)/ 自动调用实际上是主题进行调用的for (Watcher watcher : list)watcher.update(str);复制代码编写测试类:按 Ctrl+C 复制代码public class Testpublic static void main(String args)
7、Watched girl = new ConcreteWatched();Watcher watcher1 = new ConcreteWatcher();Watcher watcher2 = new ConcreteWatcher();Watcher watcher3 = new ConcreteWatcher();girl.addWatcher(watcher1);girl.addWatcher(watcher2);girl.addWatcher(watcher3);girl.notifyWatchers(“开心“);程序源码:场景 1:网上商店中商品在名称、价格等方面有变化,希望系统能自
8、动通知会员。需要在商品 product 中加入 Observer 这样角色,以便 product 细节发生变化时,Observer 能自动观察到这种变化,并能进行及时的 update 或 notify 动作.在 Java 的 java.util 包中有一个内嵌的观察者 Observer 接口,他只有一个方法:public void update(Observable o,Object arg);当被观察者对象发生变化时即调用该方法。他的第二个参数用于描述变化的特性。首先控制器(control)要想得到商品在名称、价格等方面有变化,根据面向对象设计的原则,定义两个类:NameObserver 和
9、 PriceObserver.NameObserver 主要用来对产品名称(name)进行观察的;PriceObserver 主要用来对产品价格(price)进行观察的;这两个类必须实现一个接口Observer;这两个类还必须将自己注册到被观察对象(Subject)中,这个工作由控制器(control)完成。import java.util.* ;public class NameObserver implements Observerprivate String name = “;public void update(Observable obj, Object arg) if(arg in
10、stanceof String)name=(String)arg;System.out.println(“NameObserver :name changet to “+name);public class PriceObserver implements Observerprivate float price = 0;public void update(Observable obj, Object arg) if (arg instanceof Float) price = (Float) arg).floatValue();System.out.println(“PriceObserve
11、r:price changet to“+ price);public class ProductControlprivate Product product;public setProduct(Product product)this.product = product;public register(PriceObserver priceObsv,NameObserver nameObsv)/加入观察者product.addObserver(nameobs);product.addObserver(priceobs);public void removeNameObserver(PriceO
12、bserver priceObsv)product.deleteObserver(nameobs);public void removePriceObserver(NameObserver nameObsv)product.deleteObserver(priceobs);下面是具体的被观察对象商品,这个对象 extends Observable 类,当商品在名称、价格等方面有变化,就会发送通知.public class Product extends Observableprivate String name;private float price;public String getName
13、() return name;public void setName(String name) this.name = name;setChanged();notifyObservers(name);public float getPrice() return price;public void setPrice(float price)this.price=price;/设置变化点setChanged();notifyObservers(new Float(price);数据变化后,显示在界面上的工作比较复杂.省略.测试代码如下:public class Test public static
14、 void main(String args)ProductControl productControl=new ProductControl();NameObserver nameobs=new NameObserver();PriceObserver priceobs = new PriceObserver();Product product = new Product();productControl.setProduct(product);productControl.register(nameobs,priceobs);product.setName(“橘子“);product.se
15、tPrice(1.22f);场景 2:要想实现观察者模式,则必须依靠 java.util 包中提供的 Observable 类和 Observer 接口。import java.util.* ; class House extends Observable / 表示房子可以被观察 private float price ;/ 价钱 public House(float price) this.price = price ; public float getPrice() return this.price ; public void setPrice(float price) / 每一次修改的
16、时候都应该引起观察者的注意 super.setChanged() ; / 设置变化点 super.notifyObservers(price) ;/ 价格被改变 this.price = price ; public String toString() return “房子价格为:“ + this.price ; ; class HousePriceObserver implements Observer private String name ; public HousePriceObserver(String name) / 设置每一个购房者的名字 this.name = name ; p
17、ublic void update(Observable o,Object arg) if(arg instanceof Float) System.out.print(this.name + “观察到价格更改为: “) ; System.out.println(Float)arg).floatValue() ; ; public class ObserDemo01 public static void main(String args) House h = new House(1000000) ; HousePriceObserver hpo1 = new HousePriceObserver(“购房者 A“) ; HousePriceObserver hpo2 = new HousePriceObserver(“购房者 B“) ; HousePriceObserver hpo3 = new HousePriceObserver(“购房者 C“) ; h.addObserver(hpo1) ; h.addObserver(hpo2) ; h.addObserver(hpo3) ; System.out.println(h) ; / 输出房子价格 h.setPrice(666666) ; / 修改房子价格 System.out.println(h) ; / 输出房子价格 ;