觀察者模式
觀察者模式的優(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
*/
}