在平常開發工做中,適當的使用一些設計模式,可讓代碼擴展性更強,能更好地擁抱變化,讓代碼更加優雅。本文主要介紹設計模式中的觀察者模式,並附上測試示例 Demo 供你們參考。java
觀察者模式定義了對象之間一對多的依賴關係(一的一方爲被觀察者,多的一方爲觀察者),當被觀察者狀態發生變化時,全部的觀察者可以及時收到通知,並作出相應的動做。設計模式
觀察者模式,主要應用在多個附屬業務依賴主業務的場景,附屬業務須要依賴主業務的執行結果,且主業務不須要等待附屬業務的返回結果。經過觀察者模式的應用,能夠下降主業務與附屬業務之間的耦合度,同時也提升了附屬業務的可擴展性和靈活性,可根據實際狀況,在運行時,動態追加附屬業務或移除部分附屬業務。ide
這裏,我以電商系統中,比較經常使用的退貨功能模塊爲例子來描述觀察者模式。目前大多數電商平臺都承諾7天無理由退貨,在退貨的過程當中會涉及到不少業務邏輯的處理,好比資產退還(包括在線支付和平臺資產)、積分扣減(購買商品得到積分)、修改庫存,而平臺資產又包含預存款、購物券、禮品卡等等。這裏咱們簡單舉例,以退還在線支付的金額和積分扣減爲例。在整個主要的退貨邏輯完成後,獲得須要退還的金額和須要扣減的積分,把貨款原路返還給用戶,同時把購買商品時贈送的積分扣減,其中主要的退貨邏輯就是主要業務,即被觀察者,貨款原路返還和積分扣減就是附屬業務,即觀察者。UML 圖以下:測試
從上面的 UML 圖能夠看出,被觀察者須要實現 ISubject 接口,觀察者須要實現 IObserver 接口。在被觀察者對象中,用一個集合存放全部已經註冊的觀察者,而且經過 registerObserver 或 removeObserver 方法實現觀察者的註冊或移除,經過 notifyAllObserver 方法給全部已註冊的觀察者推消息。在觀察者對象中,經過 register 和 remove 方法把觀察者本身註冊到被觀察者或從被觀察者中移除,經過 update 方法接收來自被觀察者的消息,後續若是還須要處理其餘的附屬業務,只須要添加對應的觀察者並註冊到被觀察者對象中便可,從而達到在運行時動態調整業務的效果。this
ISubject 被觀察者接口(主業務接口)spa
package observer; public interface ISubject { public void registerObserver(IObserver observer); public void removeObserver(IObserver observer); public void notifyAllObserver(); }
IObserver 觀察者接口(附屬業務接口)設計
package observer; public interface IObserver { public void update(String info); public void remove(); public void register(); }
ReturnOrder 被觀察者實體類(主業務實體類)3d
package observer; import java.util.ArrayList; import java.util.List; public class ReturnOrder implements ISubject { private List<IObserver> observerList = new ArrayList<IObserver>(); public ReturnOrder() { // TODO Auto-generated constructor stub } @Override public void registerObserver(IObserver observer) { if(observerList.indexOf(observer)==-1){ observerList.add(observer); System.out.println("添加觀察者成功..."); } } @Override public void removeObserver(IObserver observer) { int index = observerList.indexOf(observer); if(index>=0){ observerList.remove(index); System.out.println("移除觀察者成功..."); } } @Override public void notifyAllObserver() { for(IObserver observer : observerList){ observer.update("訂單1001"); } } }
IntegralObserver 觀察者實體類(積分扣減業務實體類)code
package observer; public class IntegralObserver implements IObserver { private ISubject returnOrder; public IntegralObserver(ISubject returnOrder) { this.returnOrder = returnOrder; } @Override public void update(String info) { System.out.println(info + "扣減積分..."); } @Override public void remove() { returnOrder.removeObserver(this); } @Override public void register() { returnOrder.registerObserver(this); } public ISubject getReturnOrder() { return returnOrder; } public void setReturnOrder(ISubject returnOrder) { this.returnOrder = returnOrder; } }
RefundObserver 觀察者實體類(退款業務實體類)server
package observer; public class RefundObserver implements IObserver { private ISubject returnOrder; public RefundObserver(ISubject returnOrder) { this.returnOrder = returnOrder; } @Override public void update(String info) { System.out.println(info + "退還貨款..."); } @Override public void remove() { returnOrder.removeObserver(this); } @Override public void register() { returnOrder.registerObserver(this); } public ISubject getReturnOrder() { return returnOrder; } public void setReturnOrder(ISubject returnOrder) { this.returnOrder = returnOrder; } }
TestMain 測試類
package test; import observer.IntegralObserver; import observer.RefundObserver; import observer.ReturnOrder; public class TestMain { public static void main(String[] args) { ReturnOrder returnOrder = new ReturnOrder(); IntegralObserver integralObserver = new IntegralObserver(returnOrder); integralObserver.register(); RefundObserver refundObserver = new RefundObserver(returnOrder); refundObserver.register(); returnOrder.notifyAllObserver(); returnOrder.removeObserver(refundObserver); returnOrder.registerObserver(refundObserver); } }