SAP CRM系統訂單模型的設計與實現

SAP成都研究院的一個部門領導讓我給他的團隊作一個SAP CRM One Order框架的培訓,這是我準備的培訓內容。數據庫

在Jerry以前的文章 基於SAP Kyma的訂單編排加強介紹,我表達了本身對SAP應用的理解:模型以及基於模型的增刪改查。只是同咱們大學專業課學習時完成的家庭做業相比,SAP模型的複雜程度增長了好幾個數量級。編程

和傳統的增刪改查相比,以訂單編排領域爲例,SAP訂單模型的"",還須要考慮實際業務流程中各類類型的前置和後序訂單,即SAP使用的術語 文檔流(Document Flow)設計模式

而"", 除了訂單自身狀態的遷移外,還包括訂單模型提供的各類可執行邏輯。這些邏輯既包括訂單模型自己字段的更改,也能夠包括訂單與第三方系統的交互。在不少上下文裏,咱們稱這些邏輯爲Action。緩存

以下圖右下角所示:架構

既然訂單模型複雜度如此之高,那麼引入一種精良的能支持企業級訂單編排應用的高質量建模方式,就顯得相當重要。框架

隨便看些例子,SAP CRM總共支持多少種標準的訂單類型?下圖中BUS2000開頭的就是不一樣的訂單類型,我沒有具體數過,可是幾十種老是有的。函數

而SAP Cloud for Customer,雖然位於CRM命名空間下面的Business Object的數量比SAP CRM要少一些,可是基本的用於實現銷售自動化流程的訂單模型仍然包羅萬象。性能

咱們先來看SAP CRM的訂單模型。有沒有可能用一套模型來描述SAP CRM支持的幾十種訂單類型呢?有,那就是SAP CRM One Order模型,其自描述的名稱就體現了該模型的特點。學習

Jerry曾經試圖搞清楚"One Order"這個稱呼,是來自SAP官方,仍是僅僅被SAP開發人員內部使用。優化

用搜索引擎根據關鍵字One Order搜索,獲得的結果幾乎全是Jerry寫的博客,囧。不過進系統根據ONE ORDER爲關鍵字仍是能搜索出大把的代碼。

個人文章 Jerry的WebClient UI 42篇原創文章合集裏有這張架構圖:

其中One Order框架從架構上講,位於上圖紅色區域內,包括數據庫表,ABAP結構體以及操做它們的API代碼。

SAP One Order框架有多成功?搜索引擎輸入關鍵字"SAP CRM ONE ORDER", 第一條搜索結果即Jerry寫的一篇博客。其中第一段話就給你們作了詳細的闡述:

儘管它如此成功,但當Jerry剛剛接觸One Order的時候,吃驚地發現,居然沒有一個比較直觀的圖形化界面,可以顯示出這個模型的全貌。不過瑕不掩瑜,對於一個誕生於20年前的框架來講,咱們不該該用20年後的標準來苛求它。

咱們想象一下,不一樣類型的訂單,有什麼共同點?無非每種訂單都有擡頭結構,行項目。有的結構,從業務上說能夠同時出如今訂單的擡頭行項目,好比參與訂單的業務夥伴明細(Involved parties), 組織架構(Organization Unit)等等。有的字段只有行項目才能出現,好比賣出的產品信息(Product, Scheduled Line)。

SAP One Order建模的原理,相似咱們小時候玩的積木。

組成One Order模型最小粒度的單元,就是一個個扮演積木做用的結構體,在事務碼CRMC_OBJECTS裏查看。

下圖是這些結構體的列表,若是SAP標準的結構體不能知足須要,客戶仍然能夠自行建立新的結構體。

而後咱們用搭積木的方式,將業務上具備關聯關係的若干結構體組合起來,共同分配給某個訂單類型,好比描述服務流程的訂單類型BUS2000116,就由下列這些結構體組成:

有了模型以後,剩下的就是實現基於這些模型的增刪改查操做,即ABAP編程。

One Order API的代碼實現原理,實際上就是設計模式裏的模板(Template)模式和觀察-發佈者模式的結合體。

咱們學習模板模式的時候,有一個經典的例子,上帝經過模板模式主宰芸芸衆生的生老病死。

咱們每一個人被父母實例化出來以後,只能被動地實現上帝在模板裏定義好的四個方法:生,老,病,死,而不可以更改這個模板自己,好比調換這四個方法的順序。即便是喬布斯,也沒有辦法給本身添加一個"永生"的方法。聽起來很殘酷,但這是事實

那麼,One Order框架裏,做爲One Order應用的上帝,定義了哪些模板方法?

事務碼CRMV_EVENT,指定BUS2000116, 執行:

獲得下圖列表。紅色的第一列,就是前文提到的組成One Order模型的積木。藍色的第二列,是這些積木對發生在本身身上的感興趣的事件列表。從圖中能夠看到這些事件名稱都是自描述的,好比AFTER_CREATE, BEFORE_CHANGE, BEFORE_DELETE等等。

第三列黑色的ABAP函數,就是這些事件的監聽函數。

這些監聽函數的後綴EC表明Event Callback。

藉助上述框架,One Order應用的開發人員的開發工做就變得無比輕鬆:

1. 經過搭積木的方式,定義出本身應用須要的One Order模型

2. 實現模型裏須要關注的事件對應的監聽函數。

至於這些監聽函數何時被調用到?應用開發人員徹底不用操心。

由此咱們能發現,One Order框架的實現,把編程複雜度從應用開發人員身上轉移到了框架實現身上。

One Order框架內部的實現比較複雜,一篇文章的篇幅沒法講述清楚。何況一般狀況下,One Order框架的使用者只須要了解CRM_ORDER_READ, CRM_ORDER_MAINTAIN等API的用法便可。

若是想了解更多細節,能夠參考個人SAP社區博客:

1. Buffer logic in One Order header extension Read

https://blogs.sap.com/2017/03/22/buffer-logic-in-one-order-header-extension-read/

2. Logic of FILL_OW function module in One Order

https://blogs.sap.com/2017/03/22/logic-of-fill_ow-function-module-in-one-order/

3. Logic of CHANGE_OW function module in One Order

https://blogs.sap.com/2017/03/23/logic-of-change_ow-function-module-in-one-order/

4. Logic of CREATE_OW function module in One Order

https://blogs.sap.com/2017/03/24/logic-of-create_ow-function-module-in-one-order/

5. Logic of SAVE_EC function module in One Order

https://blogs.sap.com/2017/03/23/logic-of-save_ec-function-module-in-one-order/

6. CHANGED_AT, HEAD_CHANGED_AT and CRM_CHANGED_AT in order header table

https://blogs.sap.com/2017/04/27/changed_at-head_changed_at-and-crm_changed_at-in-order-header-table/

One Order的API之一,爲消費者提供修改操做的CRM_ORDER_MAINTAIN, 全部SAP標準支持的結構體都做爲輸入參數之一出如今參數列表裏:

這種設計方法雖然讓參數列表顯得有點冗長,可是從另外一方面看,也起到了自描述的效果, 確保API的使用者即便不閱讀文檔,僅憑瀏覽這些參數自己,就能大概瞭解該API到底支持One Order哪些數據的修改。

這也符合那份著名的來自Google的API設計最佳實踐文檔裏提到的,好的API應該知足的條件之一:易學易用,自描述,不易形成誤解。

在個人另外一篇文章 Hello World, S/4HANA for Customer Management 1.0 我曾經提到,SAP CRM的部分功能遷移到SAP S/4HANA後,部分實現作了一些改造,其中就包括One Order的改造。

Jerry是負責One Order改造設計的三位人員之一,詳細的改造原理和實現我已經分享到SAP社區了,這裏只簡述一些核心概念。

爲何要改造?由於SAP CRM搬到了S/4HANA上,而S/4HANA的一個強大之處,在我同事Zhang Sean的文章 S/4HANA業務角色概覽之訂單到收款篇 裏也提到了,那就是S/4HANA在SAP歷史上第一次實現了OLTP和OLAP的完美結合,即一套系統惟一數據源,能夠同時知足Transaction事務型應用和Analytics分析報表型應用的須要。

而SAP CRM One Order沒有改造以前的模型是沒法和S/4HANA的上述特性匹配的。

改造以前,每一個組成One Order模型最小粒度的結構體,都有本身獨立的一張專屬數據庫表,命名規範通常是CRMD_加上結構體名。

這套底層存儲模型若是原封不動地搬到S/4HANA裏,在運行報表統計等應用時會出現性能問題——爲了取出報表結果,後臺須要在不少個結構體的存儲表中作各類數據庫表的內外鏈接操做。當參與鏈接操做的數據庫表尺寸增加到必定數量級後,整個應用的性能表現不佳。Jerry也參與了性能評測,最後咱們決定對One Order的底層數據模型作改造。

由於留給咱們從調研到改造的原型開發,再到正式開發一共只有八個月的時間,所以咱們選擇了一種代價最小,對One Order框架改動最小的方式。

首先咱們拋棄了以前每一個結構體擁有一張專屬數據庫表的作法,在S/4HANA裏,每種訂單類型只擁有兩張表,一張存儲擡頭級別的數據,另外一張存放行項目數據。以前散落在不一樣結構體表中的字段,現在統一維護在這兩張表裏。因爲全部的字段都平鋪在這兩張表裏,咱們內部形象地稱其爲平坦表(Flattened Table)。

存儲模型大大簡化以後,咱們基於這兩張表再建立CDS view,讓上層的報表應用消費。這樣改造後簡化的模型,能知足S/4HANA中OLAP應用的需求。

針對S/4HANA OLTP應用的改造,用一句話歸納,就是咱們採用設計模式裏的適配器模式(Adapter), 在API與簡化後的數據庫表之間引入一個微型的中間件,扮演Adapter的角色。

當消費者經過One Order API進行讀操做時,中間件負責把存儲在簡化後的數據表中的數據進行還原,再填充到One Order API上層的緩存中。對後者來講,它對底層存儲模型發生的變化絕不知情,由於Adapter封裝了底層數據讀取的邏輯並作了格式轉換,因此One Order API上層不須要作任何改動,也徹底可以像在SAP CRM裏同樣正常運行。

而當消費者調用One Order API進行寫操做時,在存儲於各個結構體對應的緩存中的數據持久化到數據庫以前,一樣是Adapter負責把這些分散在不一樣緩存結構中的數據作一個合併,合併後的結構體再寫入平坦表。

講完了CRM One Order訂單模型的設計,咱們再來簡單看看SAP Cloud for Customer的訂單模型設計。

雖然SAP Cloud for Customer的後臺對客戶和Partners不可見,但咱們仍然能夠從合法渠道得到一些其訂單模型的設計信息。

https://archive.sap.com/discussions/thread/3602400

從SAP社區上這位SAP員工的回覆,咱們得知ESF2和BOPF有不少類似之處,設計理念相似,但ESF2主要用於部署在雲端的產品,好比SAP Cloud for Customer上Business Object的開發,然後者主要服務於On Premises解決方案好比S/4HANA。

由於Jerry不可以把C4C後臺ESF2的界面給你們看,因此我選擇了展現S/4HANA的Business Object開發框架BOPF,由於前面說了,兩者不少方面都很是類似。

同以前介紹的SAP CRM One Order框架同樣,經過BOPF實現的訂單模型,一樣由若干個結構體經過搭積木的方式組成,這些結構體如上圖紅色高亮區域所示,每一個結構體也有本身的專屬存儲數據庫表。而SAP CRM One Order裏每一個結構體的事件監聽函數,採起的是ABAP傳統的面向過程的函數實現,而BOPF則採起了實現指定接口的ABAP類,兩者原理相同,只是實現細節有差別。

SAP C4C的訂單模型,雖然和SAP CRM傳統的One Order模型同樣,每一個結構體擁有一張專屬的數據庫表,可是在運行報表程序時並不會出現性能問題,這是怎麼作到的?

答案是採用了TREX,一個專爲只讀報表應用優化過的存儲倉庫。換句話說,SAP C4C的事務處理和報表處理使用的是兩套不一樣的存儲系統,這一點和S/4HANA不一樣。

SAP Cloud for Customer的訂單模型,在Cloud Application Studio裏對客戶和Partners是可見的,你們感興趣的能夠自行去查看。

但願這篇文章能讓你們對SAP CRM兩款產品中的訂單模型設計有最基礎的認識,感謝閱讀。

相關閱讀

要獲取更多Jerry的原創文章,請關注公衆號"汪子熙":

相關文章
相關標籤/搜索