當階層中為了想像中的需求新增了型別——而非因為現有需求——就出現 Speculative Hierarchy。

核心定義#

「應用有意義的泛化」要求設計者依真實需求或計畫中的需求做泛化。為「想像中的未來」預留型別會違反 YAGNI 原則

常見成因#

  • 未來防備(future-proofing):「萬一以後需要呢?」
  • 過度設計:架構師加入泛化型別來「展現專業」,實際需求並不存在。

範例:HtmlReport 階層#

Figure 6.21: HtmlReport 階層

一個程式碼分析工具支援產生 HTML 報表,未來計畫支援 .doc、.rtf、.pdf 報表。設計者另外加上「Annotation 功能」的中介抽象——但 annotation 並不在 roadmap 上。

AbstractReport → DefaultReport → AnnotatedReport → HtmlReport 形成「list-like」階層,每層只有一個子型別。其中 AnnotatedReport 完全是基於想像的需求。

建議重構#

Figure 6.22: 為 HtmlReport 階層建議的重構

套用 collapse hierarchy:移除推測性的中介型別。

對範例:

  • 保留 AbstractReportDefaultReport(這些是 roadmap 中真正會出現的)。
  • 移除 AnnotatedReport

對品質屬性的衝擊#

  • 理解性:多餘的型別讓設計複雜化。
  • 可測試性:要為虛構的擴充點寫測試。

別名#

  • Extra sub-class:抽象基底類別只被一個子類別繼承。
  • Speculative general types:父型別只有一個子型別,且自身的功能從未被使用。
  • Speculative generality:為將來不會發生的需求預留 hook 與抽象類別。
  • List-like inheritance hierarchies:每個類別最多只有一個子類別——通常是推測性泛化。