最近有粉絲在後臺給我留言,說新知識太多,「學不動了」。所謂溫故而知新,今天咱們就來重溫下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的原創文章,請關注公衆號"汪子熙":