观察者模式定义:简单的说,观察者模式定义了一个一对多的依赖关系,让一个或多个观察者对象监察一个主题对象。这样一个主题对象在状态上的变化能够通知所有的依赖于此对象的那些观察者对象,使这些观察者对象能够自动更新。
Subject(被观察的对象接口)
规定ConcreteSubject的统一接口
每个Subject可以有多个Observer
ConcreteSubject(具体被观察对象)
维护对所有具体观察者的引用的列表
状态发生时会发送通知给所有的观察者
Observer(观察者接口)
规定ConcreteObserver的统一接口
定义了一个update()方法, 在被观察对象状态改变时会被调用
ConcreteObserver(具体观察者)
维护一个对ConcreteSubject的引用
特定状态与ConcreteSubject同步
实现Observer接口,通过update()方法接收ConcreteSubject的通知
一、不使用JavaAPI的情况下
被观察的对象接口编程
package 观察者模式; /* * 被观察者接口 */ public interface Subject { //注册为一个观察者 public void registerObserver(Observer o); //取消观察者 public void removeObserver(Observer o); //通知所有观察者更新信息 public void notifyObserver(); }观察者接口实现
package 观察者模式; /* * 观察者接口 */ public interface Observer { /* * 观察者更新信息的方法 */ public void update(float price); }
package 观察者模式; import java.util.Vector; //具体的被观察者对象 public class Doll implements Subject { private Vector<Observer> v=new Vector(); private float price; public Doll(float price) { this.price = price; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; //修改价格时通知所有观察者 notifyObserver(); } @Override public void registerObserver(Observer o) { v.add(o); } @Override public void removeObserver(Observer o) { v.remove(o); } @Override public void notifyObserver() { //所有观察者更新价格 for(Observer o:v){ o.update(price); } } }具体观察者对象
package 观察者模式; public class Person implements Observer { private String name; public Person(String name) { this.name = name; } @Override public void update(float price) { System.out.println(name+"关注的娃娃价格已更新为:"+price); } }
<pre name="code" class="java">package 观察者模式; public class Test { public static void main(String[] args) { Doll doll=new Doll(3000); Person p1=new Person("小白"); Person p2=new Person("小黑"); //注册成为观察者 doll.registerObserver(p1); doll.registerObserver(p2); System.out.println("第一轮促销:"); //价格变动 doll.setPrice(2698); System.out.println("第二轮促销:"); //价格变动 doll.setPrice(2499); System.out.println("第三轮促销:"); //价格变动 doll.setPrice(1988); //将观察者p1移出 doll.removeObserver(p1); System.out.println("第四轮促销:"); //价格变动 doll.setPrice(1099); } }
二、使用JavaAPI的情况下
使用JavaAPI只需要编写具体观察者对象和具体被观察者对象,JavaAPI自定义了Observer接口和Observable类来实现抽象的观察者和被观察者对象
具体被观察者对象编程
package JavaAPI实现观察者模式; import java.util.Observable; public class Doll extends Observable{ private float price; public Doll(float price) { this.price = price; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; this.setChanged();//表示数据已改变 this.notifyObservers();//通知所有观察者进行数据更新 } }具体观察者对象编程
package JavaAPI实现观察者模式; import java.util.Observable; import java.util.Observer; //具体观察者对象 public class Person implements Observer{ private String name; public Person(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public void update(Observable o, Object arg) { if(o instanceof Doll){ Doll doll=(Doll)o; System.out.println(name+"关注的娃娃价格更新为:"+doll.getPrice()); } } }效果实现
package JavaAPI实现观察者模式; public class Test { public static void main(String[] args) { Doll doll=new Doll(3000); Person p1=new Person("小白"); Person p2=new Person("小黑"); doll.addObserver(p1); doll.addObserver(p2); System.out.println("第一轮促销"); doll.setPrice(2988); System.out.println("第二轮促销"); doll.setPrice(2699); System.out.println("第三轮促销"); doll.setPrice(1598); } }
1.观察者模式在被观察者和观察者之间建立一个抽象耦合,被观察者角色所知道的只是一个具体的观察者列表
由于被观察者和观察者没有紧密地耦合在一起,因此它们可以属于不同的抽象化层次
2.观察者模式支持广播通信。被观察者会向所有的登记过的观察者发出通知