ABAP 泛型编程(Generic Programming) 在实际工作中的一个例子
ABAP(Advanced Business Application Programming)泛型编程是一种在 ABAP 语言中使用的编程范式,它允许编写可以处理多种数据类型的通用代码。泛型编程的目的是提高代码的复用性、灵活性和可维护性。通过使用泛型编程,开发人员可以编写一种通用的算法或数据结构,而不必为每种数据类型编写特定的实现。
在 ABAP 中,泛型编程主要通过使用类型组(Type Groups)和泛型类型(Generic Types)来实现。类型组允许您定义一组相关的类型,而泛型类型允许您编写独立于特定类型的代码。例如,您可以编写一个泛型排序算法,该算法可以处理任何类型的数组,而无需为每种类型的数组编写单独的排序函数。
以下是 ABAP 泛型编程的一些关键概念:
类型组(Type Groups):类型组是一种组织和管理相关类型的方法。您可以使用 TYPE-POOL 关键字定义类型组,然后在程序中使用它们。类型组提供了一种定义类型别名和常量的方法,以便在整个程序中重复使用。
泛型类型(Generic Types):泛型类型是一种表示不确定类型的方法。这允许您编写通用的代码,该代码可以处理多种类型的数据。在 ABAP 中,泛型类型通常用 TYPE ANY 或 TYPE ANY TABLE 表示。您可以使用泛型类型编写独立于特定类型的函数、方法和类。
RTTS(Run Time Type Services):RTTS 是一组用于创建和操作动态类型的 ABAP 类和接口。使用 RTTS,您可以在运行时创建、修改和查询类型信息,从而使您的代码更加灵活和可扩展。
总之,ABAP 泛型编程允许您编写可处理多种数据类型的通用代码,从而提高代码的复用性、灵活性和可维护性。这是通过使用类型组、泛型类型和 RTTS 等技术来实现的。
我们来看现实工作中一个实际的例子。
Attachment 的metadata里定义的data type和runtime时的data type不一样
Attachment和其他四个节点不太一样。
当用新的service url访问时,https://jerry.corp:44354/sap/opu/odata/sap/CRM_ODATA/TaskCollection
动态生成的structure是BP 定义的common structure,如下:
用老的service url:https://jerry.corp:44354/sap/opu/odata/sap/CRM_TASK/Tasks?$filter
则动态生成的structure是我们task自己的attachment structure。
优化后的代码需要能够同时handle 这两种情况。我已经想到有两种办法可以工作,等做完性能测试后再update大家。
不知道BP是否也要实现类似的需求,如果是,等我把solution写出来之后再和他们的比较。
Metadata里是这个structure:
Runtime变成了这个:
这些BPID和file_size 是runtime 生成的?这个structure里header_guid也没了。
在Z class里调了半天才调通,中间遇到好多dump。
有两种办法。
方法1:如果line 15 ASSIGN失败,说明当前的internal table类型是BP定义的。
其实就是通过line 17设置的标志位,如果是BP的structure,就用BP的field symbol接,否则用task 的field symbol接。
这种方法好处是速度比较快,因为只有1处泛型处理。缺点是在代码里出现了BP的structure crmt_bp_odata_attachment_t.
方法2:这种办法从直接上能发现不需要引入对BP structure的依赖,代码里只需要我们自己的attachment structure。
- 在line 10~11 动态assign一个field symbol
- 其目的是line 23用来接真实的attachment数据,然后line 24写回到result container里去。
注意这里line 24的两个field symbol都是完全generic的,而且赋值在LOOP里完成,所以方法2的泛型处理次数为 1 + task个数。
所有高级语言的guideline都说尽量避免泛型处理,除非没其他办法。那这两种办法性能有多少差异?因为Zclass里attachment 都是hard code的,所以比较的性能差异其实就是泛型处理的overhead。
当处理10个task时,相差300微秒
100个task:方法1就比方法2快1倍了
500个task:
1000个task:
1万个task:
这时差距就甩开了,方法2所有操作都是在memory里做的,居然也消耗了0.2秒。
鉴于我们offline的use case,1千个task都算相当大的数据量了,这种情况下方法2消耗的绝对时间仍然不大,所以最后我决定采用方法2.
- 点赞
- 收藏
- 关注作者
评论(0)