iT邦幫忙

2022 iThome 鐵人賽

DAY 16
0

類別的結構

在過去 15 天的分享,我們把關注點放在變數、函式等細節上,但除了細節,要能夠寫出真正整潔的程式碼,我們還必須要在更高層次的部分付出心力。今天我們將來談談關於類別的基礎概念。

遵循標準 Java 的慣例,類別的開頭依序是:一連串變數、公用靜態常數、私有靜態變數、私有實體變數。至於公用變數,通常情況下我們不會有什麼好的理由,會在類別當中使用到這類變數。

變數宣告後會緊接著公用函式,並照著我們先前所提過的「降層法則」,讓讀者能夠輕易明白類別的內部。

值得一提的是,在 OOP 模式中我們會對類別進行封裝,並希望變數及工具函式能保持私有 (private) 狀態,但對此作者並不執著。有時會讓它們是保護 (protected) 型態,原因是這樣測試程式才能夠存取它們。
測試即王道,但我們仍會盡力保持其私有性,非不得已時才會放寬封裝的限制。

類別要簡短

我們在之前曾強調過函式必須要簡短,而類別需要簡短的重要性,就與函式一樣,這幾乎就是它們的根本。那麼與函式相同地,我們也需要問,怎樣的類別算是簡短呢?

在函式的範疇裡,我們會用行數、用內部包含的抽象概念去衡量;而在類別中,我們則會計算它職責的數量。一個包含七十個方法的類別,大多數人會同意說它太大了,甚至某些開發者會稱其為「神的類別」,那麼五個方法呢?

public class SuperDashboard extends JFrame implements MetaDataUser {
    public Component getLastFocusedComponent()
    public void setLastFocused()
    public int getMajorVersionNumber()
    public int getMinorVersionNumber()
    public int getBuildNumber()
}    

在上面的例子中,方法並不多,但它仍然包含太多的職責

經過前面關於函式的學習,我們能很快速地理解,類別的名稱要能夠描述其職責。當類別名稱無法簡單、明確地去表示該類別的職責,那可能就代表這個類別已經過大;如果名稱過於模糊,那很可能這個類別職責過多。

單一職責原則

當我們提到類別、提到職責,就不得不說大名鼎鼎的單一職責原則(Single Responsibility Principle, SRP)。
單一職責原則主張:一個類別或一個模組應該有一個,且只能有一個修改的理由。這個原則提供了關於類別職責與大小的建構方針────唯一一個修改的理由

回到上面的程式碼,我們可以發現,在 SuperDashboard 的類別中,看起來有兩個修改的理由:

  • 版本資訊:它追蹤了版本資訊,所以在每次軟體更新時它都會被一同更新。
  • 管理 Java Swing 元件: 當我們修改了任何 Swing 的程式碼,該類別都會需要更新。當然,修改 Swing 程式碼必然導致版本更新,然而反過來則未必,因為版本更新有可能源自於其他地方的程式碼修改。

所以依循單一職責原則,我們會對該類別進行重構,將不同職責的類別分離出來:

public class Version {   
    public int getMajorVersionNumber()
    public int getMinorVersionNumber()
    public int getBuildNumber()
}    

將不同的職責分離出來成為不同的類別,就如同我們將不同概念的函式分開一般,它能夠避免我們在維護程式的時候,花上大把精力在理解我們不需要了解的部分,也避免我們改動到我們不應該改動到的程式碼。


上一篇
單元測試(三)
下一篇
類別(二)
系列文
重新開始學程式,【無瑕的程式碼:敏捷軟體開發技巧守則】共讀30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言