ABAP代码规范

ABAP代码规范

本文参考GitHub项目【Clean ABAP】

命名

1. 使用描述性名称

正例:DATA customizing_entries TYPE STANDARD TABLE ...

反例:DATA iso3166tab TYPE STANDARD TABLE...

2. 优先使用解决方案域和问题域术语

在任何情况下,请勿尝试组成自己的语言。

3. 使用复数

正例:DATA countries TYPE STANDARD TABLE ...

反例:DATA country TYPE STANDARD TABLE ...

4. 使用易读的名称

宁可使用detection_object_types 也不实用 dobjt.

5. 杜绝完全不规范的缩写,避免望文不知义

反例:cust ??? "customizing", "customer", or "custom"?

6. 在各处使用相同的缩写

例如,始终将“检测对象类型”缩写为dobjt,而不是混合dotypedetobjtype

7. 类使用名词,方法使用动词

8. 用is_has之类的动词开始布尔方法

9.避免使用干扰词data,info,object

10. 鼓励您摆脱所有编码前缀

例如,result = a + b. 而不是rv_result = iv_a + iv_b.

语法

1. 面向对象优先于过程编程

2. 偏爱功能性而非程序语言构造

" MOVE 'A' TO variable.
DATA(variable) = 'A'.

" ADD 1 TO index.
index += 1.         " 版本 >=  7.54
“index = index + 1.  " 版本 <  7.54

" LOOP AT input INTO DATA(row).
"  INSERT row-text INTO TABLE result.
" ENDLOOP.
result = VALUE #( FOR row IN input ( row-text ) ).

" READ TABLE value_pairs INTO DATA(line) WITH KEY name = 'A'.
DATA(line) = value_pairs[ name = 'A' ].

" READ TABLE value_pairs TRANSPORTING NO FIELDS WITH KEY name = 'A'.
" DATA(exists) = xsdbool( sy-subrc = 0 ).
DATA(exists) = xsdbool( line_exists( value_pairs[ name = 'A' ] ) ).
IF line_exists( value_pairs[ name = 'A' ] ).

" CREATE OBJECT object TYPE /dirty/my_class.
DATA(object) = NEW /clean/my_class( ).

3. 在SQL中使用@区分程序变量和数据库列

SELECT *
  FROM spfli
  WHERE carrid = @carrid AND
        connid = @connid
  INTO TABLE @itab.

4. 在适当的地方使用设计模式

常量

1. 使用常量代替魔术数字

正例:IF abap_type = cl_abap_typedescr=>typekind_date.

反例:IF abap_type = 'D'.

2.优先于枚举类而不是常量接口

CLASS /clean/message_severity DEFINITION PUBLIC ABSTRACT FINAL.
  PUBLIC SECTION.
    CONSTANTS:
      warning TYPE symsgty VALUE 'W',
      error   TYPE symsgty VALUE 'E'.
ENDCLASS.
"or
CLASS /clean/message_severity DEFINITION PUBLIC CREATE PRIVATE FINAL.
  PUBLIC SECTION.
    CLASS-DATA:
      warning TYPE REF TO /clean/message_severity READ-ONLY,
      error   TYPE REF TO /clean/message_severity READ-ONLY.
  " ...
ENDCLASS.

"反例
INTERFACE /dirty/common_constants.
  CONSTANTS:
    warning      TYPE symsgty VALUE 'W',
    transitional TYPE i       VALUE 1,
    error        TYPE symsgty VALUE 'E',
    persisted    TYPE i       VALUE 2.
ENDINTERFACE.

3.如果不使用枚举类,则将常量分组

CONSTANTS:
  BEGIN OF message_severity,
    warning TYPE symsgty VALUE 'W',
    error   TYPE symsgty VALUE 'E',
  END OF message_severity,
  BEGIN OF message_lifespan,
    transitional TYPE i VALUE 1,
    persisted    TYPE i VALUE 2,
  END OF message_lifespan.

变量

1. 优先选择内联而不是预先声明

DATA(name) = 'something'.

"不要在可选分支中声明内联:
IF has_entries = abap_true.
  DATA(value) = 1.
ELSE.
  value = 2.
ENDIF.

"反例:
DATA  name   TYPE seoclsname.
	name = 'something'.

2. 优先选择REF TO而不是 FIELD-SYMBOL

This section is being challenged.

"1
LOOP AT components REFERENCE INTO DATA(component).
"2
LOOP AT components ASSIGNING FIELD-SYMBOL(<component>).
除非你需要使用以下:
ASSIGN generic->* TO FIELD-SYMBOL(<generic>).
ASSIGN COMPONENT name OF STRUCTURE structure TO FIELD-SYMBOL(<component>).
ASSIGN (class_name)=>(static_member) TO FIELD-SYMBOL(<member>).

3. 结构赋值

structure-type = 'A'.
structure-id   = '4711'.

or even better

structure = VALUE #( type = 'A'
                     id   = '4711' ).

1. 使用正确的表格类型

通常,将HASHED表用于大型表,这些大型表仅一步就被填充,从不修改,并且经常通过键读取。

通常,将SORTED表用于需要始终进行排序,逐位填充或需要修改,并且经常通过一个或多个完整键或部分键或按特定顺序进行处理的大型表。

STANDARD表用于较小的表(其中索引产生的收益多于收益)和“数组”(在 其中您根本不关心行的顺序,或者要完全按照附加的顺序处理它们)使用。另外,如果需要对表的不同访问,例如通过SORT和BINARY SEARCH进行索引访问和排序访问。

2.避免使用DEFAULT KEY

反例:DATA itab TYPE STANDARD TABLE OF row_type WITH DEFAULT KEY.

SORTDELETE ADJACENT语句将求助于内部表的主键,如果使用DEFAULT KEY,则可能会导致非常意外的结果

正例:明确指定关键组件 ...WITH NON-UNIQUE KEY comp1 comp2.

正例:如果根本不需要密钥,使用EMPTY KEY :...WITH EMPTY KEY.

注意:带有EMPTY KEY(没有显式排序字段)的内部表上的SORT根本不会排序

3.优先使用INSERT INTO TABLE 而不是 APPEND TO

INSERT VALUE #( ... ) INTO TABLE itab.

仅当您要以类似数组的方式使用STANDARD表时,并且要强调添加的条目应为最后一行时,才使用APPEND TO

4.优先使用 LINE_EXISTS而不是 READ TABLE or LOOP AT去判断值是否存在

IF line_exists( my_table[ key = 'A' ] ).

"反例
READ TABLE my_table TRANSPORTING NO FIELDS WITH KEY key = 'A'.
IF sy-subrc = 0.
"反例
LOOP AT my_table REFERENCE INTO DATA(line) WHERE key = 'A'.
  line_exists = abap_true.
  EXIT.
ENDLOOP.

5. 避免不必要的表读取

TRY.
    DATA(row) = my_table[ key = input ].
  CATCH cx_sy_itab_line_not_found.
    RAISE EXCEPTION NEW /clean/my_data_not_found( ).
ENDTRY.

" anti-pattern
"IF NOT line_exists( my_table[ key = input ] ).
"  RAISE EXCEPTION NEW /clean/my_data_not_found( ).
"ENDTRY.
"DATA(row) = my_table[ key = input ].

字符串

1. 使用 ` 来定义文字

CONSTANTS some_constant TYPE string VALUE `ABC`.

DATA(some_string) = `ABC`.  " --> TYPE string

" anti-pattern
DATA some_string TYPE string.
some_string = 'ABC'.

" anti-pattern
DATA(some_string) = |ABC|.

2. 使用|来动态连接字符串

DATA(message) = |Received HTTP code { status_code } with message { text }|.

" anti-pattern
DATA(message) = `Received an unexpected HTTP ` && status_code && ` with message ` && text.

布尔值

1.使用XSDBOOL设置布尔变量

DATA(has_entries) = xsdbool( line IS NOT INITIAL ).


" anti-pattern
IF line IS INITIAL.
  has_entries = abap_false.
ELSE.
  has_entries = abap_true.
ENDIF.

条件

1. 优先选择IS NOT而不是NOT IS

IF variable IS NOT INITIAL.

2. 保持较低的嵌套深度

MESSAGE

自定义消息

定义消息类统一处理提示消息

T-Code SE91 创建消息类

REPORT XX NO STANDARD PAGE HEADING MESSAGE-ID ZYC.

代码: MESSAGE E000 WITH sy-datum.

系统消息

MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
   INTO msgtext
 WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.

内外格式转换

lv_matnr = |{gt_mat-matnr ALPHA = OUT}|.

lv_matnr = |{gt_mat-matnr ALPHA = IN}|.
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值