觀察者模式

觀察者模式

觀察者模式的優(yōu)點

  • 優(yōu)點1:將觀察者與被觀察者進(jìn)行解耦,便于后期二者獨立進(jìn)行功能擴展,不會形成任何的鉗制關(guān)系。

觀察者模式的缺點

  • 缺點1:由于是鏈?zhǔn)接|發(fā),當(dāng)觀察者比較多的時候,性能問題是比較令人擔(dān)憂的。
  • 缺點2:在鏈?zhǔn)浇Y(jié)構(gòu)中,比較容易出現(xiàn)循環(huán)引用的錯誤,造成系統(tǒng)假死。

示例

被觀察者:

/**
 * 被觀察者
 */
public class ProductList extends Observable {

    private List<String> productList = null;

    /**
     * 類唯一實例
     */
    private static ProductList instance;

    /**
     * 構(gòu)造方法私有化
     */
    private ProductList() { }

    /**
     * 單例模式獲取唯一的實例(線程安全的懶漢式的單例實現(xiàn))
     *
     * @return
     */
    public static synchronized ProductList getInstance() {
        if (instance == null) {
            instance = new ProductList();
            instance.productList = new ArrayList<>();
        }
        return instance;
    }


    /**
     * 增加觀察者
     *
     * @param oberver
     */
    public void addProductListObserver(Observer oberver) {
        this.addObserver(oberver);
    }

    /**
     * 刪除觀察者
     *
     * @param oberver
     */
    public void deleteProductListObserver(Observer oberver){
        this.deleteObserver(oberver);
    }
    /**
     * 新增產(chǎn)品
     *
     * @param newProduct
     */
    public void addProduct(String newProduct) {
        productList.add(newProduct);
        System.out.println("[ProductList] add new product: " + newProduct);
        this.setChanged();
        //通知觀察者,并且傳遞新增的產(chǎn)品作為參數(shù)
        this.notifyObservers(newProduct);
    }

}

1號觀察者TaoBaoObserver

/**
 * 模擬觀察者1號:天貓旗艦店
 */
public class TaoBaoObserver implements Observer {

    @Override
    public void update(Observable o, Object product) {
        String newProduct = (String) product;
        String message = String.format("[TaoBaoObserver] receivers: %s",newProduct);
        System.out.println(message);
    }
}

2號觀察者


/**
 * 模擬觀察者2號:京東旗艦店
 */
public class JDObserver implements Observer {

    @Override
    public void update(Observable o, Object product) {
        String newProduct = (String) product;
        String message = String.format("[JDObserver] receives %s", newProduct);
        System.out.println(message);
    }
}

測試程序:


import com.netease.learn.BaseTest;
import com.netease.learn.designPattern.observer.JDObserver;
import com.netease.learn.designPattern.observer.ProductList;
import com.netease.learn.designPattern.observer.TaoBaoObserver;
import org.junit.Before;
import org.junit.Test;

import java.util.Observer;

/**
 * 觀察者模式測試類
 */
public class ObserverPatternTest extends BaseTest {

    private ProductList productList;

    private Observer jdObserver;

    private Observer taoBaoObserver;

    @Before
    public void init() {
        // 初始化被觀察者
        productList = ProductList.getInstance();

        // 初始化觀察者
        jdObserver = new JDObserver();
        taoBaoObserver = new TaoBaoObserver();
    }

    @Test
    public void test1() {
        // 觀察者添加監(jiān)聽
        productList.addProductListObserver(jdObserver);
        productList.addProductListObserver(taoBaoObserver);

        // 測試被觀察者是否將消息送達(dá)給先前訂閱消息的觀察者
        productList.addProduct("good product");

        // 觀察者取消監(jiān)聽
        productList.deleteProductListObserver(taoBaoObserver);

        // 測試被觀察者是否將消息送達(dá)給先前訂閱消息的觀察者
        productList.addProduct("bad product");
    }

    /**
     * Demo Result:
     *
     * [ProductList] add new product: good product
     * [TaoBaoObserver] receivers: good product
     * [JDObserver] receives good product
     * [ProductList] add new product: bad product
     * [JDObserver] receives bad product
     */
}

參考資料

  1. 代碼倉庫-觀察者模式
最后編輯于
?著作權(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)容