1. 程式人生 > >項目中用到的設計模式-觀察者模式

項目中用到的設計模式-觀察者模式

道理 generated 商家 商城項目 bean boolean collect 相關 not

一:觀察者模式簡單介紹

  觀察者模式又稱為發布-訂閱模式(publish/subscribe),該模式定義了一種,一對多的依賴關系,讓多個觀察者同時監聽一個主題對像,這個主題對像在狀態發生改變時,會通知所有的觀察者對像更新(執行業務邏輯)。示意圖如下:

技術分享

觀察者角色介紹:

1:抽像主題角色(Subject)抽象主題角色是一個接口,把所有對觀察者對象的引用保存在一個列表(比如ArrayList對象)裏,每個主題都可以有任何數量的觀察者。抽象主題提供一個接口,可以增加和刪除觀察者對象,抽象主題角色又叫做抽象被觀察者(Observer)角色。

2:具體主題角色(ConcreteSubject)具體主題是抽像主題接口實現類,用來管理觀察者對像的增加,刪除,通知。

3:抽像觀察者角色(Observer)為所有的具體觀察者定義一個接口,在得到主題的通知時更新自己,這個接口叫做更新接口。

4:具體觀察者角色(ConcreteObserver)該類實現抽像觀察者接口,最終業務邏輯代碼的執行類。

二:觀察者模式適用場景

1:當一個對象的數據更新時需要通知其他對象,但這個對象又不希望被通知的對象形成緊耦合
2:當一個對象的數據更新時,這個對象需要讓其他對象也鴿子更新自己的數據,但這個對象不知道具體有多少對象需要更新數據

可能上面的描述比較抽像,我舉一個例子,是去年我做電子商城項目用到的場景,商城有商品收藏,購物車等常用模塊,這些模塊都和商品價格有關,當時考慮到商品(商品數量:100000),用戶(用戶數量:100000)多了後,如果用戶將所有商品都添加到購物車,所有商品添加到收藏列表,然後用戶頻繁去查詢購物車列表,商品收藏列表,如果這兩個操作都去關聯商品表,肯定會導致查詢慢, 所以我在購物車表,商品收藏表都保存了商品的主要屬性(如:名稱,價格等),在這種環境下,如果商品價格發生變動(如:聯想電腦價格從5000漲到6000),購物車和收藏表價格肯定要跟著變化,如果不發生變化,商家和用戶會找平臺的麻煩,呵呵。不過目前和商品價格關聯的只有這三張表,但後來商城增加了促銷活動,比如抽獎,同樣的道理,我也將商品主要屬性(如:名稱,價格)保存到了促銷活動表,商城以後是否還有和商品價格相關的功能,我不知道,所以修改商品價格這個功能,觀察者模式就派上了用場。具體代碼如下:

代碼清單一,抽像主題角色:

public interface IGoodsSubject {
    void attach(IGoodsObServer observer);
    void remove(IGoodsObServer observer);
    void notify(Goods bean);
}

代碼清單二,具體主題角色:

public class GoodsObserverWork implements IGoodsSubject {
    private List<IGoodsObServer> observerList = new ArrayList<IGoodsObServer>();
    @Override
    
public void attach(IGoodsObServer observer) { // TODO Auto-generated method stub observerList.add(observer); } @Override public void remove(IGoodsObServer observer) { // TODO Auto-generated method stub observerList.remove(observer); } @Override public void notify(Goods bean) { // TODO Auto-generated method stub for (IGoodsObServer observer : observerList) { observer.update(bean); } } }

代碼清單三,抽像觀察者角色:

public interface IGoodsObServer {
    boolean update(Goods goods);
}

代碼清單四,具體觀察者角色:

//修改商品表價格
public class GoodsWork implements IGoodsObServer {

    @Override
    public boolean update(Goods goods) {
        // TODO Auto-generated method stub
        System.out.println("修改商品表價格");
        return false;
    }

}
//修改購物車價格
public class ShoppingCartWork implements IGoodsObServer{

    @Override
    public boolean update(Goods goods) {
        // TODO Auto-generated method stub
        System.out.println("修改購物車表的價格");
        return false;
    }

}

//修改收藏列表價格
public class CollectionWork implements IGoodsObServer {

    @Override
    public boolean update(Goods goods) {
        // TODO Auto-generated method stub
        System.out.println("修改收藏表價格");
        return false;
    }

}

代碼清單五,測試類:

public class Test {
    public static void main(String[] args) {
        // TODO Auto-generated method stub 
        IGoodsSubject goodsSubject = new GoodsObserverWork();
        goodsSubject.attach(new GoodsWork());
        goodsSubject.attach(new CollectionWork());
        goodsSubject.attach(new ShoppingCartWork());
        goodsSubject.notify(new Goods());
    }
}

技術分享

後記:其實使用該模式的場景還有很多,比如用戶註冊成功,需要發郵件給用戶,需要送用戶積分等,不過在項目初期,就應該考慮到哪些模塊,是否需要用到設計模式,這樣才能更好的應用設計模式。

  

項目中用到的設計模式-觀察者模式