前言:
? ? ? ?之前項目有個模塊需要實現被通知的作用,那是第一時間就想到了觀察者,那個模塊是對象間一對一的依賴關系,因此對當時找到的觀察者一對多的例子進行了簡化,在簡化過程中發現觀察者就是把一個對象放到另一處在通知時被調用,整體就是一個反向思考的過程。因此,本文也將有最完整的觀察者一步步簡化成最基本的調用代碼進行講解,不過在實際使用時,最好用觀察者的模式來實現,它也起到了一定的解耦合的作用。
觀察者模式定義:
觀察者模式也叫發布訂閱模式,對象間一種一對多的依賴關系,使得每當一個對象改變狀態,則所有依賴于它的對象都會得到通知并自動更新。
通用例子:
被觀察者
public abstract class Subject{
// Vector是線程同步,ArrayList是線程異步,這里采用Vector
private Vector<Observer> obsVector = new Vector<Observer>();
public void addObserver(Observer o){
? ? this.obsVector.add(o);
?}
public void deleteObserver(Observer o){
? this.obsVector.remove(o);
?}
public void notifyObservers(){
? for(Observer o:this.obsVector){
? ? ? ? ? ? ?o.update();
? ? }
?}
}
具體被觀察者
public class ConcreteSubject implements Subject{
//具體行為
public void doSomething(){
super.notifyObservers();
}
}
觀察者
public interface Observer{
public void update();
}
具體觀察者
public class ConcreteObserver implements Observer{
public void update(){
System.out.println(" 接收到信息,進行更新");
}
}
場景類
public class Client{
public static void main(String[] args){
ConcreteSubject subject = new ConcreteSubject();
Observer obs = new ConcreteObserver();
subject.addObserver(obs);
subject.doSomething();
}
}
簡到不能再簡之后:
public class ConcreteSubject {
//具體業務
public void doSomething(ConcreteObserver obs){
obs.update();
}
}
public class ConcreteObserver{
//更新方法
public void update(){
System.out.println(" 接收到信息,進行更新");
}
}
public class Client{
public static void main(String[] args){
ConcreteSubject subject = new ConcreteSubject();
ConcreteObserver obs = new ConcreteObserver();
// obs的屬性或行為發生變化是由subject導致的,那么就將obs傳給subject,這樣直接由subject來調用obs的函數,使其更新,從而避免了循環查詢。
subject.doSomething(obs);
}
}
因此,觀察者也是回調的一種擴展。
觀察者的優點
抽象耦合:觀察者和被觀察者都非常容易擴展。
可用于建立觸發機制,但在一個觀察者模式中最多出現一個既是觀察者又是被觀察者的情況。
觀察者的缺點
由于java中消息默認順序執行,在多級觸發情況下,需多加考慮其運行效率。