23種設(shè)計模式之觀察者模式

  • 觀察者模式底層實現(xiàn)
  • 使用java.util.Observable,java.util.Observer實現(xiàn)觀察者模式

優(yōu)點:
1:觀察者模式可以實現(xiàn)表示層和數(shù)據(jù)邏輯層的分離,定義了穩(wěn)定的消息更新傳遞機制,并抽象了更新接口,使得可以有各種各樣不同的表示層充當(dāng)具體觀察者角色。

2:觀察者模式在觀察目標(biāo)和觀察者之間建立一個抽象的耦合。觀察目標(biāo)只需要維持一個抽象觀察者的集合,無須了解其具體觀察者。由于觀察目標(biāo)和觀察者沒有緊密地耦合在一起,因此它們可以屬于不同的抽象化層次。

3:觀察者模式支持廣播通信,觀察目標(biāo)會向所有已注冊的觀察者對象發(fā)送通知,簡化了一對多系統(tǒng)設(shè)計的難度。

4:觀察者模式滿足“開閉原則”的要求,增加新的具體觀察者無須修改原有系統(tǒng)代碼,在具體觀察者與觀察目標(biāo)之間不存在關(guān)聯(lián)關(guān)系的情況下,增加新的觀察目標(biāo)也很方便。

缺點:觀察者之間有過多的細(xì)節(jié)依賴,運行效率低,程序復(fù)雜度變高。

主要用于以下情況:


image.png

關(guān)系圖:
image.png
觀察者模式底層實現(xiàn)

創(chuàng)建觀察者接口:

/**
 * 觀察者接口
 */

public interface Observer {
    void update(Subject subject);
}

創(chuàng)建主題對象:

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

/**
 * 主題對象
 */

public class Subject {

    //存放觀察者對象
    protected List<Observer> list = new ArrayList<Observer>();

    //新增觀察者對象
    public void register(Observer observer) {
        list.add(observer);
    }

    //刪除觀察者對象
    public void remove(Observer observer) {
        list.remove(observer);
    }

    //通知所有的觀察者更新狀態(tài)
    public void notifyAllObservers() {
        for (Observer observer : list) {
            observer.update(this);
        }
    }
}

創(chuàng)建具體主題對象:

/**
 * 具體主題對象
 */

public class ConcreteSubject extends Subject {

    private String content;

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
        //主題對象值發(fā)生變化通知所有觀察者
        this.notifyAllObservers();
    }
}

創(chuàng)建觀察者對象:

/**
 * 觀察者對象
 * 頭條新聞
 */

public class ObserverHeadline implements Observer {

    private String content;

    @Override
    public void update(Subject subject) {
        content = ((ConcreteSubject) subject).getContent();
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

調(diào)用:

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.util.Log;

/**
 * 這是調(diào)用者
 */

public class MainActivity extends FragmentActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //創(chuàng)建一個主題對象
        ConcreteSubject concreteSubject = new ConcreteSubject();

        //創(chuàng)建觀察者對象,比如三個
        ObserverHeadline headline1 = new ObserverHeadline();
        ObserverHeadline headline2 = new ObserverHeadline();
        ObserverHeadline headline3 = new ObserverHeadline();

        //新增觀察者對象
        concreteSubject.register(headline1);
        concreteSubject.register(headline2);
        concreteSubject.register(headline3);

        Log.d("TAG", "------------------------------------");
        //更改狀態(tài)
        concreteSubject.setContent("湖人總冠軍!");

        Log.d("TAG", headline1.getContent() + "");
        Log.d("TAG", headline2.getContent() + "");
        Log.d("TAG", headline3.getContent() + "");


        Log.d("TAG", "------------------------------------");
        //狀態(tài)再更改
        concreteSubject.setContent("火箭總冠軍!");
        Log.d("TAG", headline1.getContent() + "");
        Log.d("TAG", headline2.getContent() + "");
        Log.d("TAG", headline3.getContent() + "");
    }
}

結(jié)果:
image.png
使用java.util.Observable,java.util.Observer實現(xiàn)觀察者模式

創(chuàng)建主題對象,并且繼承java.util.Observable:

import java.util.Observable;

/**
 * 主題對象
 */

public class ConcreteSubject2 extends Observable {

    private String content;

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
        setChanged(); //表示目標(biāo)對象已發(fā)生變化
        notifyObservers(content);//通知所有觀察者
    }
}

創(chuàng)建觀察者對象,并且實現(xiàn)java.util.Observer :

import java.util.*;

/**
 * 觀察者對象
 * 音樂新聞
 */

public class ObserverMusic implements java.util.Observer {

    private String content;

    @Override
    public void update(Observable observable, Object o) {
        content = ((ConcreteSubject2) observable).getContent();
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

調(diào)用:

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.util.Log;

/**
 * 這是調(diào)用者
 */

public class MainActivity extends FragmentActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ConcreteSubject2 concreteSubject2 = new ConcreteSubject2();

        ObserverMusic music1 = new ObserverMusic();
        ObserverMusic music2 = new ObserverMusic();
        ObserverMusic music3 = new ObserverMusic();

        concreteSubject2.addObserver(music1);
        concreteSubject2.addObserver(music2);
        concreteSubject2.addObserver(music3);

        Log.d("TAG", "------------------------------------");
        //更改狀態(tài)
        concreteSubject2.setContent("周杰倫出新專輯了!");

        Log.d("TAG", music1.getContent() + "");
        Log.d("TAG", music2.getContent() + "");
        Log.d("TAG", music3.getContent() + "");

        Log.d("TAG", "------------------------------------");
        //再更改狀態(tài)
        concreteSubject2.setContent("趙雷出新專輯了!");

        Log.d("TAG", music1.getContent() + "");
        Log.d("TAG", music2.getContent() + "");
        Log.d("TAG", music3.getContent() + "");

    }
}

結(jié)果:
image.png

已完成測試!有不對的地方歡迎指出,感恩。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容