1.觀察者模式的概念
當(dāng)對象之間有一定的聯(lián)系,存在一對多的關(guān)系的時候,則要使用觀察者模式。比如,當(dāng)一個對象被修改時,則會自動通知它的依賴對象。看到這句話是不是很熟悉的感覺,沒錯我們Spring框架就是利用了這個框架去設(shè)計~
- 解決的問題:當(dāng)我們有多個對象之間存在關(guān)系的時候,一個對象改變,要改變依賴他的對象,保持高度的協(xié)作你
- 舉例:一個寢室的人都買了彩票,然后你負(fù)責(zé)觀察彩票的開獎結(jié)果,后來發(fā)現(xiàn)你們都GG了,你通知了你的室友們,那么這個時候你們的彩票可以扔了,作為彩票這個對象來說,他的狀態(tài)已經(jīng)發(fā)生了改變
- 使用場景:
1.一個抽象模型有兩個方面,其中一個方面依賴于另一個方面。將這些方面封裝在獨立的對象中使它們可以各自獨立地改變和復(fù)用。
2.一個對象的改變將導(dǎo)致其他一個或多個對象也發(fā)生改變,而不知道具體有多少對象將發(fā)生改變,可以降低對象之間的耦合度。
3.一個對象必須通知其他對象,而并不知道這些對象是誰。
4.需要在系統(tǒng)中創(chuàng)建一個觸發(fā)鏈,A對象的行為將影響B(tài)對象,B對象的行為將影響C對象……,可以使用觀察者模式創(chuàng)建一種鏈?zhǔn)接|發(fā)機(jī)制。 - 注意事項:采用觀察者模式的話,一般采用異步操作。如果采用同步操作的話,一個卡著了,會影響下面的流程
2.實現(xiàn)
我們可以圖中看到有三個比較重要的點,一個是Subject,Observer,Client。

image.png
step1:
定義一個觀察者的抽象類,然后分別實現(xiàn)三個觀察者
public abstract class Observer {
protected Subject subject;
public abstract void update();
}
public class BinaryObserver extends Observer {
public BinaryObserver(Subject subject) {
this.subject = subject;
this.subject.attach(this);//將具體的觀察者加進(jìn)去
}
@Override
public void update() {
System.out.println( "Binary String: "
+ Integer.toBinaryString( subject.getState() ) );
}
}
public class HexaObserver extends Observer {
public HexaObserver(Subject subject){
this.subject = subject;
this.subject.attach(this);
}
@Override
public void update() {
System.out.println( "Hex String: "
+ Integer.toHexString( subject.getState() ).toUpperCase() );
}
}
public class OctalObserver extends Observer{
public OctalObserver(Subject subject){
this.subject = subject;
this.subject.attach(this);
}
@Override
public void update() {
System.out.println( "Octal String: "
+ Integer.toOctalString( subject.getState() ) );
}
}
step2:
創(chuàng)建一個被觀察者
public class Subject {
private List<Observer> observers = new ArrayList<>();//用來保存觀察者
private int state;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
public void attach(Observer observer) {
observers.add(observer);
}
public void notifyAllObservers(){
for (Observer observer : observers) {
observer.update();
}
}
}
step3:
測試
public class ObserverPatternDemo {
public static void main(String[] args) {
Subject subject = new Subject();
new HexaObserver(subject);
new BinaryObserver(subject);
new OctalObserver(subject);
System.out.println("First state change: 15");
subject.setState(15);
subject.notifyAllObservers();
System.out.println("Second state change: 10");
subject.setState(10);
subject.notifyAllObservers();
}
}
開始我們將結(jié)果先設(shè)為15,后來我們設(shè)置為10;然后告訴所有觀察者,結(jié)果已經(jīng)改變了,輸出最新的狀態(tài)

image.png
3.總結(jié)
從上面的結(jié)果可以看出來被觀察者改變的話,會改變觀察者的狀態(tài);關(guān)鍵代碼就是:在抽象類里有一個 ArrayList 存放觀察者們。
鏈接:
http://www.runoob.com/design-pattern/observer-pattern.html