iT邦幫忙

2022 iThome 鐵人賽

DAY 8
0

編排的目的

這裡作者所指稱的編排,以我理解後的白話文就是:「在視覺上如何對程式碼進行排版。」
大至不同檔案、模組間的安排,小至類別 (class) 內變數與方法的書寫疏密度,都包含在此議題內。

......程式的編排是很重要的。因為太重要,所以我們不能忽略它,也因為太重要,所以我們必須嚴肅加以看待。程式的編排是一種溝通方式,而溝通是專業開發者的首要之務。

也許你覺得「讓程式碼能工作」才是專業開發者的首要之務。然而,我希望從現在開始,這本書能夠讓你重新反思這個想法。

在目前這 8 天的共讀時間裡,多少能感受到 Uncle Bob 非常在意程式碼易於閱讀這件事。而這件事是很容易理解的。
在該書作者的另一部著作【無瑕的程式碼:整潔的軟體設計與架構篇】中提到,軟體 (software) 之所以為軟體,就是在於它易於更改,否則就該稱之為硬體 (hardware)。而既然軟體易於更改也很常被更改,它的可讀性就至關重要,因為每當我們要修改程式的時候,都勢必要讀過一次。是以「可讀性」,就將是「可維護性」避不開的一環。

垂直的編排

然而作者認真看待編排的程度還是大大出乎我的意料。我甚至沒想過有任何一本講程式、講軟體的書,會提到編排這件事。

我是會對程式的視覺呈現做布局的人,但我也一直認為那只是自己對於段落的偏執,直到我讀了這篇章。

程式需要垂直的編排,而在作者的觀點裡,越是相關的變數、函式,就會放的越近,反之亦然。接下來我們會分別從垂直面上的密度、距離及順序來認識它。

垂直密度

程式與程式之間,會以空白來區隔,我們先來看點程式碼:

package futness.wikitext.widget

import java.util.regex

public class BoldWidget extends ParentWidget{
    public static final String REGEXP = "''.+?''";
    public static final Pattern pattern = Pattern.compile("''(.+?)''", Pattern.MULTILINE + Pattern.DOTALL);

    public BoldWidget(ParentWidget parent, String text) throws Exception {
        super(parent);
        Matcher match pattern.matcher(text);
        match.find();
        addChildWidgets(match.group(1));        
    }

    public String render() throws Exception {
        StringBuffer html = new StringBuffer("<b>");
        html.append(childHtml()).append("<b>");
        return html.toString();
    }

}
package futness.wikitext.widget
import java.util.regex
public class BoldWidget extends ParentWidget{
    public static final String REGEXP = "''.+?''";
    public static final Pattern pattern = Pattern.compile("''(.+?)''", Pattern.MULTILINE + Pattern.DOTALL);
    public BoldWidget(ParentWidget parent, String text) throws Exception {
        super(parent);
        Matcher match pattern.matcher(text);
        match.find();
        addChildWidgets(match.group(1));}
    public String render() throws Exception {
        StringBuffer html = new StringBuffer("<b>");
        html.append(childHtml()).append("<b>");
        return html.toString();}}

上面是兩段一模一樣的簡短程式,但缺少空白行使得第二段程式的閱讀性顯著地降低,且一旦程式的數量變多,其中的效應將更加明顯。

間隔讓程式間不同的概念被凸顯出來,變數與變數、變數與函式、函式與函式,隨著彼此間關聯性的疏密,我們也會給予它們彼此間有不同的密度。

垂直的距離

變數的宣告應該盡可能靠近變數被使用的地方,而函式也是如此。否則,我們將被迫在努力想了解整個系統在做什麼時,卻花費大把時間在尋找及記憶程式碼在哪裡。所以我會在函式的正上方去宣告變數。

let teacher;

const hireTeacher = (teacherName: string) => {
    teacher = teacherName;
}

const fireTeacher = () => {
    teacher = '';
}

如果函式的概念相近,那麼隨著它們之間的同質性越高,距離就該越短;同樣地,如果函式彼此相依,也就是說某個函式呼叫了另一個函式,那這兩個函式在垂直編排上也需要盡可能靠近,這將增加程式的可讀性。而這也呼應到了作者前面所說的「降層準則」,並帶出順序的概念。

垂直的順序

總括來說,我們希望函式呼叫呈現一種向下的相依性。也就是說,一個被呼叫的函式,應該要出現在『執行呼叫的函式』的下方。這也產生了一個良好的向下流程,由上往下查看原始碼時,可以依序發現高層模組,再接著找低層模組。

這就像是我們在寫作文,最重要的主旨會先出現,接著我們再細節地闡述、剖悉,同樣地,在程式的撰寫上,我們也會盡量先將大的概念呈現出來,再慢慢揭露出底層實現的細節。

團隊的準則

除了在垂直的面向上,水平也有其編排的原則,雖然這些原則因為現在許多 IDE 都已提供自動化的排版,而已漸漸不再被重視。書中列舉了些水平上的編排,例如縮排、加減乘除運算子的間隔,但一方面覺得這些過於細節,另一方面目前確實也不太會用到水平的編排,所以就不再細講。事實上縱然費力設計,通常在 IDE 自動重新編排後也會消失,所以現在的編排原則,最重要的應該是與團隊討論出統一的風格。

......每個程式設計師有自己偏愛的編排,但如果他身處在一個團隊裡,那他必須以團隊的編排準則為主。......我們維持一致的軟體編排風格。我們並不想讓它看起來是由一群意見不合的個體所寫成的。


上一篇
註解
下一篇
物件與資料結構
系列文
重新開始學程式,【無瑕的程式碼:敏捷軟體開發技巧守則】共讀30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言