介绍一种在ABAP内核态进行内表高效拷贝的方法,和对应的Java和JavaScript版本的伪实现
内表操作是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上:
再来看Jerry用JavaScript如何实现这个工具类的。先看在JavaScript里消费工具类的代码,仍然是声明式编程熟悉的味道:

因为function是JavaScript世界里的一等公民,所以JavaScript的实现版本,能写出更原汁原味函数式编程的解法出来:

如果要拷贝JavaScript版本的工具类CL_JS_CORRESPONDING的实现代码,可以从Jerry这篇博客里获得:
CL_ABAP_CORRESPONDING, CL_JAVA_CORRESPONDING and CL_JS_CORRESPONDING
希望这个简单的例子,能让大家感受到命令式编程和声明式编程的差异,感谢阅读。
要获取更多Jerry的原创文章,请关注公众号"汪子熙":

介绍一种在ABAP内核态进行内表高效拷贝的方法,和对应的Java和JavaScript版本的伪实现的更多相关文章
- 【ABAP系列】SAP ABAP 取两个内表的交集 比较两个内表的不同
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP 取两个内表的交 ...
- [SAP ABAP开发技术总结]内表操作
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- ABAP基础篇1 内表
内表类型 abap 内表类型有三种: 标准表(一般ABAP程序中用的最多就是这种表) 系统为该表的每一行数据生成一个逻辑索引,自己内部维护着行号(Index)的编码.表的键值不唯一,且没有按照表键自动 ...
- ABAP语法篇2 内表操作语法
VALUE MOVE-CORRESPONDING CORRESPOING FOR REDUCE GROUP BY FILTER VALUE语法: 结构赋值 ... VALUE dtype | #( ...
- ABAP中不修改内表参照的结构,给内表/结构体增加字段
Situation: DATA: itab TYPE STANDARD TABLE OF zsrsodtla_stru1, wa_itab TYPE zsrsodtla_str ...
- cpu内核态与用户态
1.操作系统需要两种CPU状态 内核态(Kernel Mode):运行操作系统程序,操作硬件 用户态(User Mode):运行用户程序 2.指令划分 特权指令:只能由操作系统使用.用户程序不能使用的 ...
- ABAP 内表 详解
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- 一种用单片机AD采样方式来检测交流市电电压的方法
下面介绍一种用单片机AD采样的方式检测市电电压的方法 要检测交流市电的电压,通常有两种方法 一.通过频繁的采样后再求平均值来获得实际电压值 二.通过采样交流市电的峰值,再通过算法得出实际电压值 这里 ...
- Linux用户态与内核态通信的几种方式
本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. Linux 用 ...
随机推荐
- 019 spring social
1.原理 2. 3. 4.
- 关于“javax.servlet.include.request_uri”属性值 include 请求 RequestDispatcher.include
在springMVC的DispatcherServlet类的doService方法中有如下代码: 1 2 3 4 5 6 7 8 9 10 if (WebUtils.isIncludeRequest( ...
- SNF快速开发平台2019-权限管理模型简介-权限都在这里
1.1 权限的概念 权限是指为了保证职责的有效履行,任职者必须具备的,对某事项进行决策的范围和程度.它常常用“具有批准……事项的权限”来进行表达.例如,具有批准预算外5000元以内的礼品费支出的 ...
- spring data jpa使用@Transactional注解开启事务后失败不回滚
如题,在数据库批量操作方法上使用@Transactional注解,其中一条数据抛出异常了,却死活不回滚. 批量操作方法是公有的,spring也是默认支持事务的,排除代码层面问题,那么就看看数据库是否支 ...
- Git采坑与问题排查
目录 Case1:代码库中存大文件 Case1:代码库中存大文件 背景 有这种情况,项目运行需要依赖一个文件(比如需要读一个文件中的数据),那么最直接的方式就是将该文件添加到代码中的分支中,然后将分支 ...
- 重温RabbitMQ
RabbitMQ是用Erlang语言实现的,它有几个概念broker:消息队列服务器实体exchange:消息交换机,它指定消息按什么规则,路由到哪个队列queue:消息队列,每个消息都会被投入到一个 ...
- F# 4.6 预览版正式公布
1月24日,F# 4.6 预览版正式公布,与以往一样,新版本的设计与开发过程是整个 F# 开源社区共同努力的结果,这次更新的具体讨论内容可以通过下面两个链接来查看: F# 4.6 意见征求记录 FSh ...
- 使用命令行操作vmware esxi -- linux
为实现自动化,发现了两种命令行工具,一是开启vmware esxi后用xshell等连接工具去连接esxi后台:二是安装powercli连接.本文将介绍一些常用的命令去操作vmware esxi 本文 ...
- 修改IP地址之后认证信息问题
$ ssh lvph@172.16.20.20 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOT ...
- Ribbon和Nignx的区别
Ribbon属于客户端负载均衡:在调用接口的时候,会通过服务别名到eureka上获取服务的信息列表,缓存到jvm本地,在本地采用RPC远程调用技术去调用接口,实现负载均衡.可以设置调用的规则是请求总数 ...