軟體設計課的學生作業:實作一個簡易的 GUI 文字編輯器。

需求#

  • 顯示檔案,支援滑鼠定位、點擊、鍵盤輸入編輯
  • 多視窗同時呈現同一份檔案
  • 支援多層 undo / redo

每個學生專案都有一個負責管理底層文字的類別,提供:

  • 載入檔案到記憶體
  • 讀取與修改內容
  • 寫回檔案

反例:專用 API#

許多團隊把文字類別寫成專用的 API:他們知道這個類別是為了互動式編輯器,於是把編輯器要支援的功能直接對應成方法。

例如:

void backspace(Cursor cursor);
void delete(Cursor cursor);
  • backspace 鍵會刪除游標左側的字元
  • delete 鍵會刪除游標右側的字元
  • 兩個方法都接受 Cursor 型別作為位置

加上選取(selection)相關功能,又新增了 Selection 類別與專用方法:

void deleteSelection(Selection selection);

為什麼這樣不好#

學生以為「文字類別的方法直接對應 UI 操作會比較好寫 UI」,但實際上:

  • 對 UI 程式碼的幫助有限
  • 對 UI 與文字類別的開發者都增加認知負擔
  • 文字類別塞滿大量淺方法,每個都只服務一個 UI 操作(例如 delete 只在一個地方被呼叫)
  • UI 開發者得認識一大堆方法

資訊洩漏#

更嚴重的是 UI 與文字類別之間的資訊洩漏:

  • UI 概念(selection、backspace 鍵等)滲透到了文字類別
  • 文字類別開發者要被迫學 UI 詞彙
  • 每加一個 UI 操作 → 文字類別就得新增一個方法
  • UI 開發者最後也得跑去改文字類別

類別設計的目標之一是「讓每個類別能獨立發展」,但專用做法把 UI 與文字類別綁死了。