項目中用到的設計模式-觀察者模式
一:觀察者模式簡單介紹
觀察者模式又稱為發布-訂閱模式(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>(); @Overridepublic 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()); } }
後記:其實使用該模式的場景還有很多,比如用戶註冊成功,需要發郵件給用戶,需要送用戶積分等,不過在項目初期,就應該考慮到哪些模塊,是否需要用到設計模式,這樣才能更好的應用設計模式。
項目中用到的設計模式-觀察者模式