最近有粉丝在后台给我留言,说新知识太多,“学不动了”。所谓温故而知新,今天咱们就来重温下ABAP里的Code Inspector的用法。面试
2015年6月,我在SAP社区上写了一篇博客,介绍了ABAP Code Inspector里一些你们不经常使用的功能,在2016年SAP社区改版,全部文章阅读量清零以后,到如今仍然有17000多的点击量。正则表达式
https://blogs.sap.com/2015/06/15/useful-tips-regarding-abap-code-inspector-that-you-may-not-know/数据库
本文是Jerry英文博客翻译成中文的浓缩版,而且假定读者都知道如何使用SCI这个事务码。对ABAP Code Inspector还不熟悉的朋友,能够查阅我另外一篇讲述其用法的博客:编程
A Small tip to get all transparent tables used in ABAP code缓存
咱们能够在ABAP Code Inspector的检查变体(Check Variant)里,根据本身的须要灵活地选择对ABAP代码进行哪一种类型的扫描动做。模块化
下图是一个例子,意思是对ABAP代码中全部对数据库表产生了读写访问之处,进行"Table Names from SELECT Statements"的扫描。该扫描的具体行为,能够点击蓝底白色的感叹号图片,以得到帮助文档。下图这个例子里勾取的选项,意思是检查被访问的数据库表,在SE11的ABAP字段里的Technical Settings是否正确被维护了,好比表的缓存类型是否设置正确。函数
Select-Statement can be transformed. X% of fields used - 检查内表字段的使用率工具
假设咱们使用SELECT * 从一张表里读取数据到ABAP内表,而后在后续代码中只使用到了A个字段,而读取的表在SE11里总共有B个字段,那么A除以B的结果越小,说明读出来的内表字段使用率越低。oop
也就是说,你或许该考虑只SELECT真正须要的字段来替代SELECT *? 只须要在上图设置里维护一个最低阀值,当Code Inspector扫描代码时,一旦检测到使用率低于维护的阀值就会报错。上图的20意思是20%.性能
Jerry 2007年刚加入SAP开始学习ABAP编程时,前辈们就告诫过我,不要在LOOP里使用SELECT语句,这样会极大影响代码的性能。
上图是经过Code Inspector扫描出来的一个例子,在双重LOOP循环里使用SELECT读取数据库表CRMD_DPP_HI_BLCK.
尽管当应用代码里嵌套循环的循环次数不大时,对代码运行的绝对时间没有太大影响——然而编写具备至少指数级时间复杂度的代码,在任何上下文里都不是一个好的编程习惯。
这个设置可以帮助咱们快速找到全部的嵌套循环。
找出全部LOOP AT ... INTO之处,理论上这些地方均可以用LOOP AT ... REFERENCE INTO或者ASSIGNING <fs>替换。当内表的行结构体字段不少时,使用后两种方式能够得到一些性能的提高。
Low-Perform. Parameter Transfers - 检测全部参数传递使用"Pass by Value"之处
Jerry关注了不少技术公众号,发现参数传递的"传引用"和"传值"这两种方式的辨析,至今仍然是不少互联网公司的面试题之一。
这个选项可让您指定针对何种类型的参数进行参数传递方式的扫描:
在ABAP里理论上采用引用传递的方式进行参数传递,性能上老是优于值传递,具体性能会提升多少,依赖于具体传递的参数类型,没法一律而论。
符合下列范式的动态SQL会被扫描出来:
Dynamic table accesses: SELECT * FROM (dbtab) WHERE … Dynamic WHERE conditions: SELECT * FROM dbtab WHERE (where_cond) Accesses to certain tables: SELECT * FROM dbtab WHERE … Client-specific accesses: SELECT * FROM dbtab FROM WA … CLIENT SPECIFIED …
这个选项并非禁止您使用动态SQL语句——事实上SAP应用的持久层里有大量的动态SQL语句的使用例子——而是提醒您别忘记了进行SQL注入的预防措施:一旦扫描出来,若是有用户输入参与了这些动态SQL语句的拼接,那就别忘记看看上下文有没有使用CL_ABAP_DYN_PRG对用户输入进行处理。
检测全部在有序内表上施加了APPEND操做的地方。有了这个扫描选项,可以帮助您避免下图第13行这种类型的运行时错误。
Jerry至今仍清楚地记得,十多年前上研究生课程《UNIX环境高级编程》时,老师不断地强调在进行系统调用以后必定要检查返回值并进行相应的错误处理。在Jerry看来,错误检测和处理是每一位编程人员都应该具有的基本素养。
对应到ABAP里,就意味着每次调用ABAP的关键字完成某项操做后,都必须检查sy-subrc的值来确认此次操做是否成功。
固然也能够根据项目的实际状况,告诉Code Inspector只检查某些类型的ABAP关键字调用。好比上图意思就是只检查READ TABLE关键字调用后是否进行了sy-subrc的检查。
在使用FOR ALL ENTRIES IN <itab>以前,必须先检查内表itab是否为空。这个选项能扫描出没有按照这个规范来编写的代码。
在这个界面里为ABAP里不一样类型的变量设置好您团队里达成一致的命名规范,而后Code Inspector就能把代码里全部违反了这些命名规范的地方扫描出来。
这个检查类别下面的设置都是一些颇有意思的统计信息。
仍是举例说明。下图红色区域的设置,意思是若是一个类的方法内的可执行语句行数超过150行,Code Inspector就报一条警告消息。这是为了不你们写出一个过于冗长的方法。
而蓝色区域的设置是若是每100行可执行代码的对应注释量小于10行,就报一条警告消息。这些阀值能够根据实际状况自行修改或关闭。
FAN-OUT Structural Metrics - 统计一个方法的扇出值
方法的扇入值和扇出值在模块化编程的上下文会常常被说起,这对概念不是编程界独创的,而是源自半导体行业里的逻辑电路设计:
逻辑门的扇出系数定义了该门可以驱动的数字信号输入的最大量,而一个代码模块的扇出值则表明了其直属下层的模块个数。
这个选项可以统计您方法的扇出系数。扇出系数过小,意味着该方法基本没有调用其余下层的函数,这有两种可能:
这个选项能够统计代码中出现的德文注释的函数。
Jerry不太明白该选项有什么用处,给非德国ABAP开发人员吐槽用的么?
这个选项也是为了防止您不经意间就创造出怪兽级的类(monster class)而生的:一旦您关注的类的属性超过设置的阀值,好比类的成员,类的公/私有方法等关注点超过选项里设置的值时,Code Inspector就会报警。
这又是一个能帮助您写出Clean ABAP code的强大工具。
什么是代码的环复杂度?
根据维基百科的定义,咱们把一段代码的执行流画成一张有向无环图,而后环复杂度能够经过下面的公式计算出来:
https://en.wikipedia.org/wiki/Cyclomatic_complexity
环复杂度 = 图的边数 - 图的节点数 + 2
这其实就是咱们研究生专业课《图论》里学的欧拉定理。
看下面这个例子:
上面这8行ABAP代码,环复杂度为3,怎么计算出来的?
先把其对应的有向无环图画出来:
这张图的边数为3,即图中黑色,红色和绿色三条粗线。 这张图的顶点数为2,如图中两个菱形的蓝色图例所示。
最后环复杂度为3 – 2 + 2 = 3.
统计代表,代码的高环复杂度和高故障率之间存在很强的正相关性,这不难理解,代码的环复杂度越高,意味着里面嵌套的IF-ELSE,SWITCH等逻辑越多,不管是代码原来的开发人员,仍是后来接手的维护人员,读起来都会以为头昏脑胀。
所以你们能够多用ABAP Code Inspector的这个扫描选项,随时监控您代码的环复杂度。
把您关注的在代码中出现的SQL操做关键字所有罗列出来。
这个选项也颇有用,能根据您指定的正则表达式扫描ABAP代码。
例如,您但愿找出代码里全部出现了READ TABLE XXX WITH KEY X = X的地方,只须要在上图的输入框里填入对应的正则表达式,即用*表明任意字符串: READ TABLE * WITH KEY * = *
而后ABAP Code Inspector就会按照咱们指望的行为去扫描代码:
ABAP Code Inspector的隐藏功能就介绍到这里,但愿你们可以好好利用它们,提升您的工做效率和代码质量,感谢阅读。
要获取更多Jerry的原创文章,请关注公众号"汪子熙":