在建構一個具備高擬真度與沈浸感的大眾運輸資訊系統時,視覺呈現的細節往往是決定系統質感的關鍵。不同營運路線的列車,其車體設計、塗裝顏色甚至是車頭造型,通常都有著截然不同的特色。為了讓使用者能在地圖上直覺地辨識出目前追蹤的是哪一條路線的列車,我們決定為系統導入「全線列車專屬繪圖資源」的功能。這意味著前端應用程式必須具備一套邏輯,能夠根據即時資料中的「路線代碼(Line ID)」,動態地載入並渲染對應的專屬車輛圖示,而非繼續使用過去那種千篇一律的通用圓點或單調的車廂圖案。
在最初實作動態圖示切換的邏輯時,負責該模組的工程師採用了程式語言中最基礎的條件判斷式:switch/case 語法。一開始,系統只有兩三條示範路線,這種寫法看似直觀且容易理解。然而,這卻是典型的技術債陷阱。隨著專案快速擴張,我們陸續接入了數十條甚至上百條不同的運輸路線。這導致原本簡單的 switch/case 區塊暴脹成了一個長達數百行的「巨獸級」函數。每次只要設計團隊新增或修改了一張列車圖片,開發人員就必須去修改這個龐大的函數,手動加上新的 case 判斷。這種做法不僅違反了軟體工程中著名的「開閉原則(Open-Closed Principle)」,還極度容易引發人為失誤,例如拼字錯誤或是漏加了 break 導致邏輯崩潰。整個程式碼庫的維護性因此大幅下降,每次部署新路線的視覺更新都令人提心吊膽。
為了徹底解決這個擴展性危機,我們在近期的程式碼重構週期中,對這段邏輯進行了全面開刀。我們決定捨棄冗長且僵化的條件判斷,轉而採用「動態字典映射(Dynamic Dictionary Mapping)」的設計模式。我們建立了一個獨立的設定檔,在其中宣告一個 JavaScript 物件(或稱為 Map),將路線代碼直接對應到圖檔的路徑字串。在渲染邏輯中,我們只需將傳入的路線代碼作為物件的鍵值(Key)去查詢,就能在常數時間複雜度 O(1) 內立即取得正確的圖片路徑。如果查詢不到,系統則會優雅地退回使用一個預設的通用列車圖示。這樣的重構不僅將原本數百行的冗餘程式碼精簡到了不到十行,更重要的是,它將「資料」與「邏輯」徹底分離。未來新增路線圖示時,開發者只需在設定檔中新增一行鍵值對即可,完全不需要碰觸核心的渲染邏輯。
function getTrainImagePath(lineId) {
let imagePath = '';
// 坑:隨著路線增加,無限膨脹且難以維護的 switch/case
switch (lineId) {
case 'red_line':
imagePath = '/images/trains/red.png';
break;
case 'blue_line':
imagePath = '/images/trains/blue.png';
break;
case 'green_line':
imagePath = '/images/trains/green.png';
break;
// ... 下略 100 行重複程式碼 ...
default:
imagePath = '/images/trains/default.png';
}
return imagePath;
}
// 將資料抽離為獨立的配置物件 (Dictionary)
const TRAIN_ASSETS_MAP = {
'red_line': '/images/trains/red.png',
'blue_line': '/images/trains/blue.png',
'green_line': '/images/trains/green.png',
// 新增路線只需在此添加一行鍵值對
};
function getTrainImagePath(lineId) {
// 解法:利用物件鍵值查詢,優雅且具備極佳擴展性
return TRAIN_ASSETS_MAP[lineId] || '/images/trains/default.png';
}
雖然這次的更新核心主要聚焦於程式碼架構的淨化與開發流程的最佳化,但它為最終使用者帶來的體驗躍升卻是深遠的。首先,由於架構變得極具擴展性,我們的設計與開發團隊現在能夠以極快的迭代速度,將節慶限定塗裝、特殊主題列車(例如彩繪列車)的視覺更新推送到使用者的畫面上。使用者在開啟地圖時,將驚喜地發現每一條路線的列車都完美還原了真實世界中的樣貌。這種對細節的堅持與豐富的視覺回饋,大幅提升了系統的在地化親和力與操作趣味性。使用者不再只是面對冷冰冰的資訊儀表板,而是彷彿在俯瞰一個充滿生機、色彩繽紛的微縮城市交通網,帶來了前所未有的視覺享受與互動沈浸感。