内表操作是ABAP開發人員幾乎在每個ABAP程式裡都會遇到的。
看一個例子:有兩個行結構不一樣的内表,每個内表的行結構有三列,除了name這一列名字一緻外,其他兩列的名稱都不同,下圖用紅色和藍色标注出來。
如果要把内表developer_list裡的兩位開發人員Jerry和Tom的資訊按照下圖的映射關系拷貝到内表presale_list裡:
正常做法當然是用一個LOOP循環,引入兩個臨時變量,先把内表1逐行賦給臨時變量1,再把臨時變量1逐列賦給臨時變量2.
在ABAP 750版本裡,提供了一個輔助類cl_abap_corresponding,能以聲明式程式設計的方式完成這個内表複制任務。
通過工具類的create方法,第二行和第三行指定要進行複制操作的源和目标内表,第四到六行告訴工具類内表複制的列字段映射規則。之後第8行調用execute方法完成複制操作。
大家更喜歡哪一種方式?這個例子雖然簡單,但包含了一個程式設計領域的基礎知識點:指令式程式設計(Imperative Programming)和聲明式程式設計(Declarative Programming)。
第一種使用LOOP循環的解法是典型的指令式程式設計的例子,我們定義了兩個臨時變量,通過循環體内的三條指派指令,指令代碼去執行以完成内表拷貝。第二種解法, 作為應用開發人員,我們隻是向工具類做出聲明,我們想對哪兩個内表根據什麼樣的映射邏輯進行拷貝。至于工作類如何執行,應用開發人員不操心,這就是聲明式程式設計。
當然,即便是聲明式程式設計,工具類的代碼也總得有人實作。輕按兩下execute方法,發現是ABAP核心态的C語言實作的。
對于SAP客戶和partners來說,無法看到這個ab_kmMvcdExecute核心方法的源代碼,詳情參考Jerry的文章:
聊聊C語言和ABAP。
大家可以試着自己用ABAP來模拟實作一個自己的CL_ABAP_CORRESPONDING. 這裡Jerry提供一份Java版本的實作。
Java裡萬物皆對象,是以我們分别定義Developer和Presale類:
建立兩個Java list來模拟ABAP裡的内表:
然後我的目的是,把第一個list裡,Jerry和Tom這兩位開發者的name, focusLanguage和salary字段分别賦給第二個list對應執行個體的name, focusArea和salaryPlusBonus字段,模拟一個公司内部轉崗的操作。
同ABAP使用工具類的方式一樣,我聲明了兩條映射規則,分别是第二行的mapping執行個體1,将focusLanguage字段直接賦給focusArea字段,以及第5行的mapping執行個體2,将salary字段的值乘以2,再賦給salaryPlusBonus字段。最後調用execute方法完成指派。為了便于ABAP開發人員同之前的ABAP内表拷貝的例子進行比對,這裡雖然是Java代碼,但是CL_MAPPING和CL_JAVA_CORRESPONDING這兩個類,我仍然用的是ABAP的命名規範,而非Java的駝峰式命名。
CL_JAVA_CORRESPONDING的實作如下:execute調用map, map調用mapEach,提取使用者指定的映射規則裡的字段名,使用Java反射機制完成操作。
完整代碼位于Jerry的[github](
https://github.com/i042416/JavaTwoPlusTwoEquals5/tree/master/src/corresponding)上:
再來看Jerry用JavaScript如何實作這個工具類的。先看在JavaScript裡消費工具類的代碼,仍然是聲明式程式設計熟悉的味道:
因為function是JavaScript世界裡的一等公民,是以JavaScript的實作版本,能寫出更原汁原味函數式程式設計的解法出來:
如果要拷貝JavaScript版本的工具類CL_JS_CORRESPONDING的實作代碼,可以從Jerry這篇部落格裡獲得:
CL_ABAP_CORRESPONDING, CL_JAVA_CORRESPONDING and CL_JS_CORRESPONDING希望這個簡單的例子,能讓大家感受到指令式程式設計和聲明式程式設計的差異,感謝閱讀。
本文來自雲栖社群合作夥伴“汪子熙”,了解相關資訊可以關注微信公衆号"汪子熙"。