設計模式之觀察者模式(Observer Pattern)

模式分析:

    觀察者模式又稱爲發佈/訂閱(Publish/Subscribe)模式。java

   觀察者模式定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態發生變化時,會通知全部觀察者對象,使它們可以自動更新本身。編程

UML類圖:

    

接口分析:

    Observerable:被觀察者接口,規定了幾個方法,分別是registerObserver():表示將觀察者註冊到被觀察者中,即「訂閱」;removeObserver():表示將觀察者從被觀察者中移除,即「取消訂閱」;notifyObservers():當被觀察者狀態改變的時候,這個方法被調用,通知全部已經註冊的觀察者。ide

    ConcreteObserverable:被觀察者,實現了Observerable接口,對以上的三個方法進行了具體實現,同時有一個List集合,用以保存註冊的觀察者,等須要通知觀察者時,遍歷該集合便可。注意,該集合的泛型參數應該是Observer,接口類型,而不該該是具體的Observer實現類,這樣作的緣由是一個被觀察者可能會有多個不一樣實現類的觀察者(但都實現了Observer接口),若是限定了某一個具體的類型,那麼會致使之後要加入新類型的時候而不得不修改當前類,耦合度太高,這是一個很是很差的行爲。(設計原則:面向接口編程而不是面向實現編程)。this

    Observer:觀察者接口,規定了update()方法,當被觀察者調用notifyObservers()方法時,觀察者的update()方法會被回調。spa

    ConcreteObserver:觀察者,實現了update()方法。設計

DEMO:

//定義被觀察者
public interface Observerable {

    void registerObserver(Observer observer);

    void removeObserver(Observer observer);

    void notifyObservers();
}

//定義觀察者
public interface Observer {

    public void update(int edition, float cost);
}

public class MagazineData implements Observerable {

    private List<Observer> observerList;
    private int edition;
    private float cost;

    public MagazineData(){
        observerList = new ArrayList<>();
    }

    @Override
    public void registerObserver(Observer observer) {

        observerList.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {

        int i = observerList.indexOf(observer);
        if(i >=0){
            observerList.remove(i);
        }

    }

    @Override
    public void notifyObservers() {

        observerList.stream().forEach(item ->{
            item.update(edition, cost);
        });
    }

    public void setInfomation(int edition, float cost){

        this.edition = edition;
        this.cost = cost;

        notifyObservers();
    }
}

public class Customer implements Observer{

    private String name;
    private int edition;
    private float cost;

    public Customer(String name){
        this.name = name;
    }

    @Override
    public void update(int edition, float cost) {

        this.edition = edition;
        this.cost = cost;
        buy();
    }

    public void buy(){
        System.out.println(name+"購買了第"+edition+"期的雜誌,花費了"+cost+"元。");
    }
}

public static void main(String[] args) {

        MagazineData magazineData = new MagazineData();

        Observer customerA = new Customer("A");
        Observer customerB = new Customer("B");
        Observer customerC = new Customer("C");

        magazineData.registerObserver(customerA);
        magazineData.registerObserver(customerB);
        magazineData.registerObserver(customerC);

        magazineData.setInfomation(5, 20);
}

 

推模型:被觀察者主動向觀察者推送自身的信息,能夠是所有信息或者是部分信息。3d

拉模型:被觀察者經過把自身的引用傳遞給觀察者,須要觀察者自行經過該引用來獲取相關的信息。code

 

認識Java內置的觀察者模式:

  • java.util.Observerable(類)
  • java.util.Observer(接口)

使用場景:

        好比咱們有兩個對象,一個對象依賴於另外一個對象的變化而變化,此時咱們能夠將這兩個對象抽象出來,作成接口,利用觀察者模式來進行解耦,又或者,當一個對象發生變化的時候,須要通知別的對象來作出改變,但又不知道這樣的對象有多少個,此時利用觀察者模式很是合適。server

參考例子對象

相關文章
相關標籤/搜索