编程风格是一个经久不衰的话题,你们所公认的事实是:一个良好的编程风格会带来不少的好处。而对于“良好”的标准,则众说纷纭,莫衷一是。编程风格在ABAP程序中固然也有着重要的意义,由于不多看到专门针对ABAP编程风格的讨论,我决定把我知道的事情总结出来,以抛砖引玉。欢迎看到这篇文章的朋友回复讨论。html
2018.01.11更新:本文中提到的大部份内容能够经过Code Inspector进行检查,Github上面的一个开源检查项目abapOpenChecks提供了至关全面的检查,强烈建议读者使用。相关文档地址:http://docs.abapopenchecks.org/checks/程序员
本文连接:http://www.cnblogs.com/hhelibeb/p/6814045.html sql
原创内容,转载请注明数据库
如咱们所知,ABAP是一种大小写不敏感的语言。这天然会引发一个问题:使用大写仍是小写?SAP给出的ABAP编辑器为咱们提供了4种选项:编程
选择(关键字)大写,让代码的其他部分保持小写,在我看来是一个极为天然的选择。理由是,一)阅读大写字母组成的文本比阅读小写字母组成的文本要难。二)程序的读者一般会对关键字极为熟悉(即便不熟悉,也有文档可看),而做者本人以外的读者,对做者写出的非关键字不太可能熟悉。这两个理由使得,相比关键字,咱们更须要让代码的非关键字保持良好的可读性。所以,非关键字的小写是一种必然的选择。在此基础上,让关键字保持大写,能够帮助咱们区分关键字和非关键字。固然,因为关键字高亮的功能的存在,也能够不经过大小写区别它们,因此(所有)小写一样是一种可行的选项,部分SAP标准代码也是这样的风格。api
某些开发者会告诉新人:代码最好所有大写,这样能够避免本身不小些将大写参数设定为小写(ABAP中不少字符参数是大写的)。然而,因为上述的缘由,这是一件很糟糕的事情。字符的值的大小写和代码的大小写彻底是两码事,由于这种理由放弃代码的可读性,是不成立的。编辑器
听说不少程序员常年为了缩进的问题争论不休,ABAP开发者在这方面是幸福的,由于SE38的代码编辑器提供了自动缩进的功能,这使得只要点击“格式优化”,全部人的代码会获得一样的缩进...ide
我尚未使用过新的编辑器——ABAP Development Tools for Eclipse。也许在这个新的IDE普及以后,人们会对ABAP的缩进产生新的见解。工具
ABAP是一门包含有大量关键字的语言。SAP彷佛意识到了关键字过多带来的不便,在尝试着在近期的更新中引入更多表达式的写法。post
表达式的写法比关键字更加简洁、可读,推荐尽可能使用表达式代替关键字,好比:
"实例化对象 DATA(e_receiver) = NEW event_receiver( )."推荐的写法 DATA e_receiver TYPE REF TO event_receiver. "不推荐的写法 CREATE OBJECT e_receiver.
*调用方法(能够看到,传统的写法竟然要5行...) val = object->method( parameter = a ) "建议的写法 CALL METHOD object->method "不建议的写法 EXPORTING parameter = a RECIEVING return = val.
*访问内表 SELECT * INTO TABLE @DATA(itab) FROM sflight UP TO 10 ROWS ORDER BY carrid. TRY. DATA(ls_sflight) = itab[ 2 ]. "推荐的写法 CATCH cx_sy_itab_line_not_found. ENDTRY.
DATA(ls_sflight) = value #( itab[ 2 ] optional ). "更推荐的写法 ,value表达式能够自动捕捉异常 DATA ls_sflight TYPE sflight. READ itab INTO ls INDEX 2. "不推荐的写法 IF sy-subrc <> 0. ENDIF.
有关更多表达式写法的例子能够参考这个博客:ABAP 7.4新特性,或者ABAP Objects,以及SAP的官方文档。
若是要从一个数据库表中取得它自身的两个字段比较后的到的条目,ABAP的新手可能会这样写:
SELECT carrid connid fldate seatsocc seatsmax FROM sflight INTO TABLE sflight_tab WHERE seatsmax < sflight-seatsocc.
而有经验的/看过文档的人知道上面的代码会报错,正确的写法是这样:
SELECT carrid connid fldate seatsocc seatsmax FROM sflight INTO TABLE sflight_tab WHERE seatsmax < sflight~seatsocc.
区别就在与-和~。
不过第一种写法在某些状况下也是能够运行的,若是程序中有这样的声明的话:
DATA: BEGIN OF sflight, carrid TYPE sflight-carrid, connid TYPE sflight-connid, fldate TYPE sflight-fldate, seatsocc TYPE sflight-seatsocc, seatsmax TYPE sflight-seatsmax, END OF sflight, sflight_tab LIKE STANDARD TABLE OF sflight WITH EMPTY KEY.
此时程序也能够运行,不过比较不会发生在数据库字段之间,而是会以本地定义的结构sflight中的seatsocc做为条件。
要避免这类混淆的发生,可使用转义字符@,加在SQL语句中的Host Variables前面。
若是是想比较数据库内的字段的话:
SELECT carrid, connid, fldate, seatsocc, seatsmax FROM sflight WHERE seatsmax < sflight~seatsocc INTO TABLE @sflight_tab.
而若是是想要以ABAP程序内的值做为条件的话,就要在它的前面也加上@:
SELECT carrid, connid, fldate, seatsocc, seatsmax FROM sflight WHERE seatsmax < @sflight-seatsocc INTO TABLE @sflight_tab.
这样就不会混淆了~
(注:本节的内容来自一篇英文博客:Why the new Open SQL Syntax is Better)
此外,在S4/HANA中,SAP推荐将更多的计算内容放到数据库中。为了实现这一目的,如今Open SQL具备CASE表达式、字符串表达式、CAST、CTE等多种新功能。咱们应该尝试使用它们。
ABAP程序一般使用一系列前缀来为变量命名,好比:
LT_ = Local internal table
LS_ = Local structure(work area)
LR_ = Local reference
GT_ = Global internal table
GS_ = Global structure(work_area)
GR_ = Global reference
这样作是有好处的,一方面,一般的ABAP编辑器不具有自动提示类型的功能,合理前缀能够下降阅读代码的心智负担;另外一方面,如上一节所述,若是为变量取一个和数据类型/数据库字段彻底相同的名字,会在某些状况下产生意外的混淆。好比:
DATA s1 LIKE sflight. DATA s2 TYPE sflight. "以上这段代码会声明两个相同的结构s1, s2 DATA sflight TYPE i. DATA s1 LIKE sflight. DATA s2 TYPE sflight. "若是声明过一个名为sflight的i类型变量,则使用like的语句会声明一个i类型的s1,使用type的语句会声明一个有着sflight行类型的结构s2..
可是前缀的滥用也会致使不少问题,合理的ABAP代码中应该尽可能避免多余的变量名前缀。
好比
使用lv/gv的前缀来表示本地变量/全局变量,是一个比较不明智的作法。由于,一个变量是值这种事情一般是无需说明的。v能够被看成默认值省略,而lt/lc则有意义。
一样的,为form命名时也不该当存在这种无心义的前缀:
由于一般来讲,form的使用是经过PERFORM关键字来实现的:
PERFORM get_price.
这时,get_price显然不多是form以外的任何存在。使用frm_这样的前缀,不能带来任何理解上的帮助,只会增长代码阅读的难度。
2019.07.23更新:
QQ群里有群友质疑:lv_是通行的命名前缀,l_会带来混淆,让开发者感到困惑。
在这里回应下,首先,这种命名方式并非笔者的发明,
sap的不少代码中的变量会用l_或m_做为前缀,好比咱们最经常使用的cl_gui_alv_grid中的一些成员变量的前缀就是m_。笔只是认同这种办法的合理性。
在命名中,前缀后面的东西比前缀重要不少,因此要尽量下降前缀的复杂性,避免浪费读写代码的时间。使用l_而非lv_可能会稍微增长命名上的复杂性,可是若是开发者能够在一开始掌握一个稍微复杂点的规则,也许能够在后面省更多力气。
有种观点认为,单行的代码长度不该超过80个字符。大致上,对于ABAP代码而言,我赞成这个观点。
如图,80个字符已经稍稍超出了编辑器核心区域的边界(虽然远未达到ABAP支持的单行最大长度——255字符)。若是只是打开单个编辑器窗口的话,这种长度还能够接受,但若是要并排打开2个窗口,一部分代码也许会没法直接显示。
此外,在SAP自身的代码比较工具中,过长的单行内容是没法直接展现的:
这种状况下,须要点击工具栏中的按钮换页:,很是不利于阅读。若是能有意限制单行代码的长度,就能够避免处于这种不利的状况。
也许每一个ABAP初学者学习的第同样东西都是内表,而学习内表时要学会的首要事项就是工做区、带表头的内表与不带表头的内表的区别....会有教程告诉他们用OCCURS关键字声明一个带表头的内表,
DATA: BEGIN OF lt_numbers OCCURS 0, num1 TYPE i, num2 TYPE i, END OF lt_numbers.
或者这样,使用WITH HEADER LINE,
DATA: lt_sflight TYPE STANDARD TABLE OF sflight WITH HEADER LINE.
若是这样作的话,声明获得的内表就会表明两样东西,好比,lt_sflight实际上表明着做为表头的结构lt_sflight、和内表自己lt_sflight[],至于在具体的代码中它到底表明哪一个,只能由语境和开发者的意图决定...
这种奇怪的特性彷佛是为了开发人员的方便而设计的,但在生产实践上,它使得开发者极易不慎将一个名称表明的两个实体混用,从而写出有bug的代码。SAP在乎识到本身的错误以后,把这两种声明方式标记为过期的语法,而且在OO模式下,会在语法检查中提示这一点。
然而,为了兼容旧有的程序,在report和function group等类型的程序中,人们依然可使用这两种方式声明带表头的内表。不少古老的ABAP教程也大量地使用了它们。以致于很多新人无心识地把它们看成声明内表的合理方式。据说某些公司在规范中禁止了它们的使用,在2017年的如今,我认为这是一项很是合理的举措,用同一个名字表明两样不一样的东西原本就是很很差的事情。为了让书写者不至于混淆、为了让读者更好的理解代码,请放弃带表头的内表。与之相似的tables关键字,也应避免使用。
参考: ABAP Programming Guidelines
BEST PRACTICE GUIDELINES FOR DEVELOPMENT – USEFUL TIPS FOR ABAP DEVELOPMENT