觀察者模式 -- 設計模式系列文章(二)

  • 概述

  在平常開發工做中,適當的使用一些設計模式,可讓代碼擴展性更強,能更好地擁抱變化,讓代碼更加優雅。本文主要介紹設計模式中的觀察者模式,並附上測試示例 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);
    }

}

 

歡迎轉載,轉載必須標明出處 

相關文章
相關標籤/搜索