2016 年 06 月 的封存

柏林版如何進化程式碼

Metric和Audits這2個功能早已經存在Delphi很多年了, Metric和Audits可以讓我們檢查和保證程式碼的撰寫品質, 但就我個人所知經常使用Metric和Audits的開發人員卻很少, 我也不知道為什麼.

在我於各地進行Delphi相關的活動中,也認識了一些朋友, 他們可能是專案/產品經理, 因為他們通常都會詢問一些類似的問題, 例如:

  1. Delphi有沒有工具確保外包程式碼的品質?
  2. Delphi有沒有工具確定外包廠商有遵守我們的制定的程式碼規範?
  3. 如何尋找程式碼中的漏洞和弱點?
  4. 等等…

等問題. 事實上Metric和Audits就可以幫助開發人員確保程式碼的品質, 在柏林版中又加入了Toxicity功能可以幫助開發人員制定和搜尋程式碼規範. 例如我看過許多公司都規定一個函式長度不能超過多少行, 一個if敘述不能超過多少層, 以及函式的參數不能超過多少個等.

這些程式碼規範有的和日後維護的難易有關, 有的和執行效率有關, 都是非常實用的規範, 但在數萬或是數十萬行的程式碼中要如何驗證巨量的程式碼呢?

在柏林版中開發人員可以在IDE中點選Tools|Options|Toxicity Metrics啟動Toxicity的設定對話盒:

Snap1

在Toxicity Metrics設定對話盒你可以看到我們可設定驗證函式長度, 函式參數數目, if敘述層, 以及函式需要測試的獨立執行路徑數目等重要的程式碼品質數據.

接著你可以開啟Delphi專案, 在IDE右上方的搜尋欄中輸入Toxicity, 就可以看到Toxicity命令:

Snap4

執行它, 它就可以開始對你的Delphi專案進行驗證, 並顯示結果:

Snap2

不合驗證規範的函式就會以紅色標誌, 使用滑鼠雙擊紅色標誌項目IDE就會開啟對應的程式碼. 例如上面的函式DeductAmount是一個非常複雜的函式, 它使用的if敘述層有6個, Toxicity功能可以即時又精確的在數萬行的程式碼中幫助我們定位到這個函式:

Snap3

接著我們就可以再次檢驗DeductAmount函式是否真的需要如此複雜, 可不可以藉由重構簡化它呢?

善加使用Audits/Metrics和Toxicity功能可以不斷的完善和提昇程式碼品質, 當然也可以幫你驗證他人或是外包的程式碼. Have Fun!

 

 

 

 

 

廣告

1 則迴響

柏林版的隱藏功能

還記得在Delphi 3的時代有一本相當有名的書籍” Hidden Paths of Delphi 3: Experts, Wizards and the Open Tools API”,它討論了當時Delphi 3一些鮮為人知的功能, 非常的有趣. 不過我今天並不是要著墨這本書, 而是因為柏林版推出後大多數為人熟知的新功能就是就的安裝程式, IoT的新功能以及新的C++編譯器.不過柏林版也有一些人們忽略的好康, 就像是隱藏版的功能一樣, 今天就讓我們看看有些什麼看不見的好東西.

我有個多年的習慣就是在安裝新版的Rad Studio之前都會把前一版的原始程式保留下來並和新版的原始程式比較, 研究之用. 在安裝完柏林版之後就可以很方便的啟動Beyond Compare來比較, 研究有興趣的程式碼:

Snap2

例如柏林版提到了StrReplace和一些其他功能改善, 然而言語之間很模糊,我也不太清楚真正的改善是什麼, 因此我就使用Beyond Compare直接來比較, 發現柏林版許多的RTL都有改寫的跡象, 例如下圖就是使用Beyond Compare來比較StrReplace:

Snap1

而發現了巨大的改變. 如果我們在IDE中搜尋StrReplace在RTL/VCL/FMX中使用的情形可以發現StrReplace是一個熱點函式, 也就是說StrReplace是被大量使用的函式:

Snap3

而且String的helper class也大量的使用了StrReplace:

function TStringHelper.Replace(OldChar, NewChar: Char): string;

begin

  Result := System.SysUtils.StringReplace(Self, OldChar, NewChar, [rfReplaceAll]);

end;

 

function TStringHelper.Replace(OldChar: Char; NewChar: Char; ReplaceFlags: TReplaceFlags): string;

begin

  Result := System.SysUtils.StringReplace(Self, OldChar, NewChar, ReplaceFlags);

end;

 

function TStringHelper.Replace(const OldValue, NewValue: string): string;

begin

  Result := System.SysUtils.StringReplace(Self, OldValue, NewValue, [rfReplaceAll]);

end;

嗯, 這代表如果柏林版改善了StringReplace函式那麼就代表幾乎所有有使用到字串處理的程式都會得到助益, 但我們並不知StringReplace到底改善了多少? 柏林版的StringReplace到底有沒有比以前版本的StringReplace好呢?

要找答案很簡單, 寫一個大量使用StringReplace的範例程式比較一下不就得了?如果只是改善3~5%, 那就…..

下面是同樣的程式, 只是一個用西雅圖版編譯, 一個用柏林版編譯.這支程式在一個公開的電子書中呼叫StringReplace來取代字串, 下面執行的結果可能會令人大吃一驚, 因為柏林版的StringReplace比西雅圖版快上數百倍, 令人印象深刻:

Snap4

嗯, 柏林版的這個隱藏功能太棒了, 當你處理字串資料的應用程式使用柏林版重新編譯之後您有沒有發現執行速度似乎變快了呢? Have Fun!

 

 

2 則迴響