1. 程式人生 > 其它 >Java實現觀察者(釋出-訂閱)模式

Java實現觀察者(釋出-訂閱)模式

觀察者模式(Observer),也叫釋出-訂閱模式(Publish-Subscribe)
觀察者模式涉及到被觀察的主題(Subject)與觀察者(Observer)2個角色,主題釋出訊息,觀察者響應訊息。
觀察者可以訂閱主題,也可以取消訂閱。

觀察者模式示例:主播與粉絲

  • 主題(釋出者)是直播網站主播,其業務是線上直播;
  • 觀察者(訂閱者)是主播的粉絲,只要主播開始直播,就通知粉絲
  • 粉絲不喜歡主播了,可以取消訂閱
  • 一個主播可以有多個粉絲,一個粉絲也可以訂閱多個主播

觀察者介面

update方法是每個觀察者必須實現的方法,用於響應主題傳送的訊息,其引數是主題傳遞給觀察者的資料

public interface Observer
{
    // 更新
    void update(String anchorName,boolean online);
}

主題(釋出者)介面

public interface Subject
{
    // 註冊觀察者
    void registerObserver(Observer observer);
    // 移除觀察者
    void removeObserver(Observer observer);
    // 通知所有觀察者
    void notifyObservers();
}

觀察者具體實現類

觀察者可以有任意多個,這裡只寫一個示例

// 粉絲遲漢
public class ChiHan implements Observer
{
    @Override
    public void update(String anchorName,boolean online)
    {
        if(online)
        {
            System.out.printf("主播%s上線了!快去看她!%n",anchorName);
        }
        else
        {
            System.out.printf("主播%s下線了!可以睡了!%n",anchorName);
        }
    }
}

主題(釋出者)具體實現類

主題可以有多個,這裡只寫一個示例

// 主播馮提莫
public class FengTimo implements Subject
{
    private boolean online;
    private List<Observer> fans;

    public FengTimo()
    {
        this.online=false;
        this.fans=new ArrayList<>();
    }

    @Override
    public void registerObserver(Observer fan)
    {
        fans.add(fan);
    }

    @Override
    public void removeObserver(Observer fan)
    {
        fans.remove(fan);
    }

    @Override
    public void notifyObservers()
    {
        fans.forEach(fan->{
            fan.update("馮提莫",online);
        });
    }

    // 主題狀態改變後,通知所有觀察者
    public void setOnline(boolean online)
    {
        this.online=online;
        onlineChanged();
    }

    public void onlineChanged()
    {
        notifyObservers();
    }
}

測試

public static void main(String[] args)
{
    // 主播(主題)
    FengTimo fengTimo=new FengTimo();
    // 粉絲(觀察者)
    Observer chiHan=new ChiHan();
    // 註冊觀察者
    fengTimo.registerObserver(chiHan);

    // 主題狀態改變,自動通知觀察者
    fengTimo.setOnline(true);
    fengTimo.setOnline(false);
    // 移除觀察者,觀察者將不再收到訊息
    fengTimo.removeObserver(chiHan);
    fengTimo.setOnline(true);
}

輸出

主播馮提莫上線了!快去看她!
主播馮提莫下線了!可以睡了!