SAP ABAP 裡存在 Java List 這種集合工具類麼?CL_OBJECT_COLLECTION 瞭解一下
![](http://mdimg.wxwenku.com/getimg/ccdf080c7af7e8a10e9b88444af983934cf02aada58319ab451bab764f089063f0d66d207adb9048a3cf2fc1deb631e0.jpg)
Jerry 以前在工作中交替做著 ABAP 和 Java 開發時,總是在使用一種語言時,懷念另一種語言的便利之處,比如用 ABAP 開發時,懷念 Java 裡以 List 為代表的功能強大,使用方便的集合工具類。
![](http://mdimg.wxwenku.com/getimg/6b990ce30fa9193e296dd37902816f4bc138efb0c166f891bce1c7c9a19aef5dd8d501131b31a340237952c3d8490138.jpg)
List 或許是眾多 Java 初學者最先接觸和掌握的 Java 集合工具介面之一。以最具代表性的實現類 ArrayList 為例,檢視其原始碼,發現 ArrayList 不過就是用面向物件的程式設計方式封裝了對一個物件陣列的常用操作,使其不僅支援 Java 原生 Array 的所有功能,同時也支援前者不具備的動態擴容功能。
![](http://mdimg.wxwenku.com/getimg/ccdf080c7af7e8a10e9b88444af98393e010f7c052723eb87835790462768897127277fdaa22ab295ebe5dc680522f21.jpg)
對 Java 稍有了解的開發者,要自己仿照著寫出一個同樣的 ArrayList 實現,並不是一件困難的事情。不過 List 介面和其眾多實現類都是 Java 開發包的一部分,這使得 Java 開發者做應用開發時不用重複造輪子,可以直接使用,非常方便。
那麼 SAP ABAP 裡存在類似的集合工具類麼?
首先我們有內表,具備 Java Array 的所有功能,並且功能和使用靈活度上來說都遠勝後者。但內表的操作畢竟是一種面向過程的程式設計思路。ABAP 裡存在類似 Java List 的介面嗎?
通過之前檢視 Java ArrayList 的實現原始碼,我們可以仿照其思路,在 ABAP 裡實現一個一模一樣的 ABAP ArrayList 出來,只需要定義一個行型別(Table Line)為物件引用的內表變數,再用面向物件程式設計方式實現對這個內表變數插入,刪除,和按索引訪問的功能即可。而 Java ArrayList 的動態擴容,ABAP 內表原生就支援。
![](http://mdimg.wxwenku.com/getimg/356ed03bdc643f9448b3f6485edc229b86a140876887eabdf985e1a1fc1756e920d32da828e4c8055ac1fbcc2ec090fa.jpg)
事實上 SAP CRM 就採取了這種實現思路,CL_CRM_BOL_ENTITY_COL,這個工具類,從名稱上就能判斷出它是 BOL 例項的儲存容器,提供了容器內 BOL 例項元素的插入,刪除和遍歷的功能。
![](http://mdimg.wxwenku.com/getimg/6b990ce30fa9193e296dd37902816f4b6e92dd20fc9933f76f486d6f96ef4be24c35062dea5720efb10e01d353179e10.jpg)
然而這個列表只能插入型別為 BOL 例項的元素,有更通用的 ABAP List 工具類麼?那就是 CL_OBJECT_COLLECTION, 提供了類似 Java ArrayList 對列表元素的基本操作:
-
插入
-
刪除
-
按索引訪問
-
遍歷
-
清空列表
![](http://mdimg.wxwenku.com/getimg/356ed03bdc643f9448b3f6485edc229b08cd577f540c7f58ef5709ac2fdace6ab66e825d057f80eb893e92b327e51273.jpg)
這個工具類內部維護的內表型別為 TYPE STANDARD TABLE OF REF TO OBJECT, 因此可插入指向任何物件例項的引用。
![](http://mdimg.wxwenku.com/getimg/356ed03bdc643f9448b3f6485edc229b45661658f60a772b3d5ea2b8541ca20c779075f03b2f32621a589dfc2aebc769.jpg)
Jerry 這篇部落格曾經介紹過該工具類的一個使用例子:
CL_OBJECT_COLLECTION, iterator and Polymorphism
假設我們要開發一個計算圖形面積的應用,支援圓形和長方形。實現兩個類 ZCL_CIRCLE 和 ZCL_RECTANGLE, 分別按照圓形和長方形的面積計算公式,實現 GET_AREA 方法。
![](http://mdimg.wxwenku.com/getimg/ccdf080c7af7e8a10e9b88444af983933ad85adbc76dd7de8f0c0820f7ee1f96b7eab4bf1a5c51b3aa1f07620c9ff3d0.jpg)
![](http://mdimg.wxwenku.com/getimg/ccdf080c7af7e8a10e9b88444af9839381532c8667ba8af142a0f64b88e40aca116a4b1b90049abdb7613b51200cef54.jpg)
傳統的實現方式
定義一個 Table Line 型別為通用的物件引用(TYPE REF TO OBJECT)的內表 lt_shape,用於存放圓形和長方形的例項物件引用。
![](http://mdimg.wxwenku.com/getimg/ccdf080c7af7e8a10e9b88444af98393fd0dad75e82c08f6cb73060ea88f3939dc47def257614062cc5792e61adf6f20.jpg)
每次建立圓形或者長方形的物件例項之後,新增到內表中,然後 LOOP 內表,逐行取出元素,用 IS INSTANCE OF 關鍵字,判斷當前記錄指向的是圓形還是長方形例項,再用 CAST 進行強制型別轉換,呼叫對應的面積計算方法。
![](http://mdimg.wxwenku.com/getimg/ccdf080c7af7e8a10e9b88444af9839355a57439bff992a5e819ccdbf8ebe9447019ea5c5c12ab8e3f4f573ec4cf71df.jpg)
這種實現方式,在 LOOP 裡有 IF ELSE 判斷,IS INSTANCE OF 和 CAST 這三種非常醜陋的寫法。將來如果要支援其他圖形比如三角形的面積計算,又得在 LOOP 裡新增新的 ELSE 分支,這違反了程式設計的開閉原則-對擴充套件開放,對修改封閉。
採用 CL_OBJECT_COLLECTION 的多型實現
定義一個新的介面 ZIF_SHAPE,圓形和長方形的類均實現自這個介面:
![](http://mdimg.wxwenku.com/getimg/356ed03bdc643f9448b3f6485edc229b756a852355c945f365de6a30fc194ec2bd62e0132c56eb85e8ca9cad66001201.jpg)
![](http://mdimg.wxwenku.com/getimg/356ed03bdc643f9448b3f6485edc229bb521a3778b878b4f457c2f57f2fb42a35a0af2b295ec700e55512e0ebff8c7a7.jpg)
藉助 CL_OBJECT_COLLECTION, 採取面向物件程式設計裡多型(Polymorphism)的思路,我們不僅避免了醜陋的 IF-ELSE,繁瑣的型別探測 IS INSTANCEOF 和強制型別轉換 CAST,同時將程式碼行數從 37 行減少到了 20 行。將來要是得增加對其他圖形的支援,只需要新建圖形類並實現,而無需修改下面的計算邏輯。
![](http://mdimg.wxwenku.com/getimg/ccdf080c7af7e8a10e9b88444af983939a97b7cfd4878c253fd3b5808c6f9b381c73c2368231b18c81f60d756e366db0.jpg)
當然這個例子如果不用 CL_OBJECT_COLLECTION, 而是每次把實現了 ZIF_SHAPE 介面的圖形類例項,加入到 TABLE LINE 型別為 TYPE REF TO OBJECT 的內表裡,然後直接 LOOP 內表,也可以達到同樣的效果。本文只是為了演示 CL_OBJECT_COLLECTION 的用法,故而沒有使用內表來完成計算。
本例實際上是迭代器設計模式的一個具體應用。迭代器設計模式是提供一種訪問底層物件集合而不暴露底層表示的方法。Iterator 將訪問物件集合的邏輯從 collection 物件本身解耦。這種解耦在遍歷不同型別的集合物件時提供了額外的優勢。
Iterator 還提供了根據需求以不同方式遍歷集合的靈活性。如果我們將 position 嵌入到 Collection 物件本身中,它將不允許我們以不同的方式實現多重訪問。迭代器從 Collection 物件中獲取訪問的責任,並將其放在自己內部。迭代器提供了訪問底層資料結構的唯一介面。客戶端不需要知道正在訪問的集合物件的型別。
希望本文能幫助大家通過 ABAP 工具類 CL_OBJECT_COLLECTION 實現迭代器設計模式的做法有一個最基礎的瞭解。
感謝閱讀。
劃線
評論
複製
- 那些 Go 語言發展歷史上的重大決策
- 從趨勢到挑戰,一站式解讀作業系統運維和可觀測性
- 百萬級 Topic,騰訊雲的 Apache Pulsar 穩定性實踐
- Apache Doris 在思必馳的應用優化實踐:海量語音通話資料下,實時、離線一體的數倉架構設計實踐
- 愛數正式開源認知智慧開發框架 KWeaver
- 運維智慧化的三大關鍵技術
- “抄我的還‘反捅’我一刀”,Gary Marcus 發文駁斥圖靈獎得主 Yann LeCun
- 當出海成為必選項,企業如何構建全場景全生態技術底座?
- 數智底座必備能力三:快速構建創新應用
- Docker 多階段構建實戰 (multi-stage builds)
- 工作筆記之 SELECT 語句在 SAP ABAP 中的用法總結(上)
- 經久不衰的設計定律是不要讓我思考的設計
- 不要指望下一個像 GPT 這樣的大型語言模型會民主化
- Java 近期新聞:Helidon Níma、Spring Framework、MicroProfile、MicroStream、Kotlin 和 Piranha
- 一文入門 jQuery
- C 學習 ---__libc_open 函式的原理
- 監控系統工作原理
- 甲骨文新微服務框架 Helidon Níma:使用虛擬執行緒實現高效能
- 【雲原生 | 從零開始學 Kubernetes】二、使用 kubeadm 搭建 K8S 叢集
- Elasticsearch 聚合學習之四:結果排序