把文字類別做得更通用:API 只用「基本文字操作」來定義,不反映將來會用它建出來的高階 UI 操作。

通用版本的核心介面#

修改文字只需兩個方法:

void insert(Position position, String newText);
void delete(Position start, Position end);
  • insert:在文字中任意位置插入任意字串
  • delete:刪除位置在 startend 之間的字元
  • Position(更通用)而非 Cursor(特定於 UI)

再加上一個「位置運算」工具:

Position changePosition(Position position, int numChars);
  • 從某位置出發、移動 numChars 個字元,得到新位置
  • 正數往後、負數往前
  • 自動跨行處理

用通用 API 實作 UI 操作#

// delete 鍵:刪掉游標右邊一個字元
text.delete(cursor, text.changePosition(cursor, 1));

// backspace 鍵:刪掉游標左邊一個字元
text.delete(text.changePosition(cursor, -1), cursor);

為什麼這樣比較好#

比較項目專用 API通用 API
單一 UI 操作的程式行數較短略多一點
顯而易見需到文字類別找文件 / 讀程式碼UI 程式碼就能看出字元怎麼被刪
文字類別中的方法數多(且淺)少(且深)
整體程式碼量較多較少

UI 開發者真正關心的是「backspace 到底刪了哪些字元」。

通用 API 把這件事直接寫在 UI 程式碼裡,一目了然——而專用 API 反而要繞到文字類別才能搞清楚。

通用 API 的可重用性#

文字類別寫成通用後,可以用在編輯器以外的場合。

例子:寫一個「把檔案中所有 X 替換成 Y」的應用。

  • 專用版的 backspace / delete 對這個用途毫無價值
  • 通用版的 insert / delete 已經涵蓋了大半需求
  • 唯一差的可能是搜尋方法:
Position findNext(Position start, String string);

而真實的編輯器多半也需要搜尋取代功能,這個方法反正會加進來。