1. 程式人生 > >2018-7-20-observer-model

2018-7-20-observer-model


layout: post
title: ‘觀察者模式’
subtitle: ‘’
date: 2018-07-20
categories: 設計模式
cover: ‘’
tags: 觀察者模式 設計模式

個人網站:https://tinuv.me/
**更好的閱讀體驗請訪問:https://tinuv.me/2018/07/02/188.html

介紹

觀察者模式屬於行為型模式.當物件存在一對多的關係時,使用觀察者模式.比如當一個物件被修改時,自動通知它的依賴物件

分析

我覺得很重要的一點是搞清哪一個是觀察者,哪一個是被觀察者,就是說到底是觀察者還是被觀察者,從它的另一個名字:訂閱釋出模式

可以知道很明顯就是釋出者也就是被觀察者,是訂閱者,也就是觀察者.從這兩個名字的措辭來看,這兩個名字的主被動關係剛好完全被顛倒.從易理解角度看,訂閱釋出模式的名字可能更好.

所以分析的結果就是:

: 釋出者,被觀察者
: 訂閱者,觀察者

練習

說明

  • 被觀察者

被觀察者,狀態的改變是通過這個物件釋出給觀察者的,也有可能是作為被觀察者和觀察者的橋樑,與觀察者和被觀察者都關聯,被觀察者把狀態的改變傳遞給這個橋樑,橋樑把這個狀態的改變再發布給釋出者.

  • 觀察者

觀察者被動的接受被觀察者釋出資訊,所以說訂閱釋出模式更符合這種模式的叫法,觀察者通常設計會設計一個成抽象類或者介面,因為觀察者往往有很多,這種設計容納一些頂層設計.

示例

觀察者設定為一個抽象類(個人認為不優雅)

  • 被觀察者基類

通常基類有三個函式addObserver(Observer observer),removeObserver(Observer observer)和一個抽象函式publishMessage(),addObserver(Observer observer)函式用來繫結觀察者和被觀察者,removeObserver(Observer observer)函式用來移除觀察者和被觀察者的繫結關係(訂閱關係),值得注意的是,如果是通過抽象類的方式,那麼觀察者必須要持有被觀察者的引用,繫結關係的新增和移除通常都由觀察者(訂閱者)進行,這也是我認為這種方式不優雅的原因,因為觀察者通常有多個,這種會造成程式碼維護困難,但好處是把訂閱和解除訂閱的權利交給了觀察者

import java.util.ArrayList;
import java.util.List;

public abstract class Observeable {

    List<Observer> Observers = new ArrayList<>();

    public void addObseriver(Observer observer){
        Observers.add(observer);
    }

    public void removeObserver(Observer observer){
        Observers.remove(observer);
    }

    public abstract void publishMessage();

}
  • 被觀察者

被觀察者必須實現publishMessage(),這個方法是一個通知訂閱的物件的函式,因為要傳遞的事件或者說引數具體都不同.

public class Observe extends Observeable {

    private String state;

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
        publishMessage();
    }

    @Override
    public void publishMessage() {
        for (Observer observer:Observers){
            observer.receiveMessage();
        }
    }
}
  • Observer基類

Observer擁有一個類似receive()的抽象函式,子類實現這個函式用來處理被觀察者傳遞過來的事件或者資料,如果是通過抽象類的方式來實現觀察者模式,那個每個Observer必須持有一個Observe物件

public abstract class Observer {

    public abstract void receiveMessage();

    protected Observe observe;
}

  • Observer子類

Observer子類實現Observer基類,擁有訂閱和解除訂閱的權利,通過實現抽象函式receiveMessage()來處理被觀察者傳遞過來的事件或者資料


public class FristObserver extends Observer {

    public FristObserver(Observe observe){
        this.observe = observe;
        observe.addObseriver(this);
    }


    @Override
    public void receiveMessage() {
        System.out.println("frist observer receive message"+observe.getState());
    }
}
觀察者通過介面的方式實現觀察者模式

這是觀察者模式非常通用的形式,觀察者必須實現這個介面,這種方式下,是一種中央集權的方式:只有被觀察者有權力新增和移除觀察者物件(其實都是通過被觀察物件新增或解除訂閱關係,只是位置不同而已)

  • Observe基類Observeable
import java.util.ArrayList;
import java.util.List;

public abstract class Observeable {

    List<Observer> Observers = new ArrayList<>();

    public void addObseriver(Observer observer){
        Observers.add(observer);
    }

    public void removeObserver(Observer observer){
        Observers.remove(observer);
    }

    public abstract void publishMessage();

}
  • Observe
public class Observe extends Observeable {

    private String state;

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
        publishMessage();
    }

    @Override
    public void publishMessage() {
        for (Observer observer:Observers){
            observer.receiveMessage(state);
        }
    }
}

  • Observer介面
public interface Observer{

    void receiveMessage(String message);
}
  • Observer實現類
public class FristObserver implements Observer {


    @Override
    public void receiveMessage(String message) {
        System.out.println("frist observer receive message"+message);
    }

}
通過泛型的方式實現觀察者模式(以後再說)