轉:SAP BAdI 實現原理解析

來源:互聯網
上載者:User

 

轉自:http://jgtang82.iteye.com/blog/114737

 

SAP BAdI 實現原理解析

關鍵字: badi, adapter, proxy, factory

最近幾天發現這篇文章被單擊的次數比較高, 這裡把文檔內容再充實一下:

本文談得是SAP BAdI 機制背後的一些設計問題, 關於如何使用BAdI請參考:
...

在SAP系統中 BAdI 相關類的 類圖 如下:
 

下面能過程式碼分析 BAdI 機制背後的一些設計問題:
1. 定義指向BAdI interface的Reference
DATA: exit_ref TYPE REF TO ZIF_EX_BADI.

2. 獲得繼承BAdI interface的子類執行個體
CALL METHOD cl_exithandler=>get_instance
    CHANGING
        instance = exit_ref.

這裡的cl_exithandler=>get_instance方法是一個簡化的Abstract Factory.
    a) 為什麼說它是個簡化的Abstract Factory呢? 因為CL_EXITHANDLER沒有一個抽象的工廠類, 只有一個產品簇, 只完成單一的建立工作。
    b) 為什麼不說它是個Factory Method? 是因為它沒把類的建立工作延遲到子類。
    c) 為什麼cl_exithandler=>get_instance要用原廠模式呢?
在Client代碼端看來,通過調用get_instance這個方法就可以得到具體實作類別執行個體,然後調用下面的方法:
CALL METHOD exit_ref->CUSTOM_VALIDATION
    IMPORTING
        param = 'xxx'
    EXPORTING
        flt_val = 'xxx'.
就調用到實作類別中的介面方法了。

但通過Debug代碼你會發現這個調用返回的是Adapter Class 'ZCL_EX_BADI'而非我們的Impl Class!
其實這就是建立型模式的意義 - 隱藏對象的建立細節.
也就是說當我們調用CUSTOM_VALIDATION時,其實是調用了ZCL_EX_BADI->CUSTOM_VALIDATION.

3. ZCL_EX_BADI->CUSTOM_VALIDATION,這個方法是SAP系統自動產生的,核心代碼如下:

  1. ...
  2. LOOP AT INSTANCE_BADI_TABLE ASSIGNING <exit_obj></exit_obj>
               WHERE METHOD_NAME  = 'DISPLAY'.   
  3.     APPEND TO EXIT_OBJ_TAB.   
  4. ENDLOOP.   
  5. ...
  6. LOOP at exit_obj_tab ASSIGNING  <exit_obj></exit_obj>
        WHERE ACTIVE   = SXRT_TRUE.   
  7.     CHECK <exit_obj></exit_obj>-imp_class NE old_imp_class.   
  8.     <flt_cache_line></flt_cache_line>-valid = sxrt_true.   
  9.     flt_val_db = <exit_obj></exit_obj>-flt_val.   
  10.     ...   
  11.     MOVE <exit_obj></exit_obj>-imp_class to <flt_cache_line></flt_cache_line>-imp_class.   
  12.     MOVE <exit_obj></exit_obj>-imp_switch to <flt_cache_line></flt_cache_line>-imp_switch.   
  13.     MOVE <exit_obj></exit_obj>-order_num to <flt_cache_line></flt_cache_line>-order_num.   
  14.     INSERT INTO TABLE INSTANCE_FLT_CACHE.   
  15.     old_imp_class = <exit_obj></exit_obj>-imp_class.   
  16. ENDLOOP.   
  17. ...
  18. LOOP AT INSTANCE_FLT_CACHE ASSIGNING <flt_cache_line></flt_cache_line>   
  19.        WHERE flt_name    = flt_name   
  20.          AND valid       = sxrt_true   
  21.          AND method_name = 'CUSTOM_VALIDATION'.   
  22. ...   
  23. CALL METHOD ('CL_FOBU_METHOD_EVALUATION')=>load   
  24.   EXPORTING   
  25.     im_class_name     = <flt_cache_line></flt_cache_line>-imp_class   
  26.     im_interface_name = 'ZIF_EX_BADI'   
  27.     im_method_name    = 'CUSTOM_VALIDATION'   
  28.   RECEIVING   
  29.     re_fobu_method    = <flt_cache_line></flt_cache_line>-eo_object   
  30.   EXCEPTIONS   
  31.     not_found         = 1  
  32.     OTHERS            = 2.   
  33. ...   
  34. ENDLOOP.  

這時我們會發現這段代碼會找到所有Active的BAdI Implemention然後去執行它。這裡有點Adpater的味道而且在SAP標準文檔中確實是把ZCL_EX_BADI 類為Adapter Class, 但是我覺得這個叫法不合適,改變介面不是這個類的主要價值,裡面的Loop調用實作類別方法和Filter顯得更主要。所以它的主要價值應該是對實作類別的存取控制,改稱Adapter Class為 Proxy或許更合適。下面是Proxy模式的類圖:
 
關於Proxy模式, 《Head First Design Pattern》中講的非常不錯,這裡推薦一下。

總結:
1. 通過 Factory 獲得Adapter Class 的執行個體 (障眼法 / 封裝建立細節)
2. 通過 Proxy 對象(Adapter Class) 實現對 BAdI Implementations 的存取控制

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.