當對象間存在一對多關系時,則使用觀察者模式(Observer Pattern)。比如,當一個對象被修改時,則會自動通知它的依賴對象。觀察者模式屬于行為型模式。
關鍵代碼:在抽象類里有一個 ArrayList 存放觀察者們。
優點: 1、觀察者和被觀察者是抽象耦合的。 2、建立一套觸發機制。
缺點: 1、如果一個被觀察者對象有很多的直接和間接的觀察者的話,將所有的觀察者都通知到會花費很多時間。 2、如果在觀察者和觀察目標之間有循環依賴的話,觀察目標會觸發它們之間進行循環調用,可能導致系統崩潰。 3、觀察者模式沒有相應的機制讓觀察者知道所觀察的目標對象是怎么發生變化的,而僅僅只是知道觀察目標發生了變化。
注意事項: 1、JAVA 中已經有了對觀察者模式的支持類。 2、避免循環引用。 3、如果順序執行,某一觀察者錯誤會導致系統卡殼,一般采用異步方式。
- 創建 Observer 類。
/*** 1. 創建 Observer 類。* @author mazaiting*/
public abstract class Observer {protected Subject subject;public abstract void update();
}
- 創建 Subject 類。
/*** 2. 創建 Subject 類。* @author mazaiting*/
public class Subject {private List<Observer> observers = new ArrayList<Observer>();private int state;public int getState() {return state;}public void setState(int state) {this.state = state;notifyAllObservers();}/*** 添加觀察者*/public void attach(Observer observer){observers.add(observer);}/*** 通知全部觀察者更新數據*/public void notifyAllObservers(){for (Observer observer : observers) {observer.update();}}
}
- 創建實體觀察者類
/*** 3. 創建實體觀察者類。* @author mazaiting*/
public class BinaryObserver extends Observer{public BinaryObserver(Subject subject) {this.subject = subject;this.subject.attach(this);}@Overridepublic void update() {System.out.println( "Binary String: " + Integer.toBinaryString(subject.getState())); }}/*** 3. 創建實體觀察者類。* @author mazaiting*/
public class OctalObserver extends Observer{public OctalObserver(Subject subject) {this.subject = subject;this.subject.attach(this);}@Overridepublic void update() {System.out.println( "Octal String: " + Integer.toOctalString( subject.getState() ) );}}/*** 3. 創建實體觀察者類。* @author mazaiting*/
public class HexaObserver extends Observer{public HexaObserver(Subject subject) {this.subject = subject;this.subject.attach(this);}@Overridepublic void update() {System.out.println( "Hex String: " + Integer.toHexString( subject.getState() ).toUpperCase() ); }}
- 使用Subject和實體觀察者對象
/*** 4. 使用 Subject 和實體觀察者對象。* @author mazaiting*/
public class Client {public static void main(String[] args) {Subject subject = new Subject();new HexaObserver(subject);new OctalObserver(subject);new BinaryObserver(subject);System.out.println("First state change: 15");subject.setState(15);System.out.println("Second state change: 10");subject.setState(10);}
}
- 打印結果
First state change: 15
Hex String: F
Octal String: 17
Binary String: 1111
Second state change: 10
Hex String: A
Octal String: 12
Binary String: 1010