观察者模式
一、观察者模式的概念
观察者模式:定义了一对多的依赖,当被观察者改变时,所有的观察者都会收到改变的通知。
应用场景:Java Swing
注意:被观察者可以充当观察者,观察者也可以充当被观察者,也就是说,观察者模式是可以嵌套使用的。
观察者的实现方式有”推“和“拉”两种,使用推的方式虽然方便但是可能会推给观察者它并不需要的消息,拉的方式实现起来相对麻烦一些。
二、UML图
双方都存有对方基类型的引用,被观察者使用观察者的引用调用update()方法推送信息,观察者使用被观察者的引用注册或者在“拉”的方式下拉取信息。
三、代码
推的方式
Observable.java
public interface Observable { void addObserver(Observer o); void removeObserver(); void notifyObserver(); }
Subject.java
public class Subject implements Observable{ private LinkedList<Observer> list = new LinkedList<>(); private int data = 1; public void addObserver(Observer o) { list.add(o); } public void removeObserver() { } public void notifyObserver() { for(Observer o : list) { o.update(data); } data++; } }
Observer.java
public interface Observer { void update(int data); }
A.java
public class OA implements Observer{ OA(Observable ob) { ob.addObserver(this); } public void update(int data) { System.out.println("OA Receive " + data); } }
B.java
public class OB implements Observer{ OB(Observable ob) { ob.addObserver(this); } public void update(int data) { System.out.println("OB Receive " + data); } }
Test.java
public class Test { public static void main(String[] args) { Observable obser = new Subject(); Observer oa = new OA(obser); obser.notifyObserver(); Observer ob = new OB(obser); obser.notifyObserver(); } }
拉的方式
主要来关注这两种方式的不同点
Subject.java
public class Subject implements Observable{ private LinkedList<Observer> list = new LinkedList<>(); private int data = 1; public void addObserver(Observer o) { list.add(o); } public void removeObserver() { } public void notifyObserver() { for(Observer o : list) { o.update(); } data++; } public int getData() { return data; } }
A.java
public class OA implements Observer{ private Observable ob; OA(Observable ob) { this.ob = ob; ob.addObserver(this); } public void update() { System.out.println("OA Receive " + ob.getData()); } }
其实Java类库中是有内置的Observable和Observe类的,使用起来方便,但是和自己实现的观察者模式比起来是缺乏弹性的,因为类库的设计是类,是类就要继承,继承致命的缺点就是牵一发而动全身,他日类库中的类一旦有变化维护起来相当困难。