編程風格是一個經久不衰的話題,你們所公認的事實是:一個良好的編程風格會帶來不少的好處。而對於「良好」的標準,則衆說紛紜,莫衷一是。編程風格在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