
假設你的系統有兩個變化軸:付款流程(線上、線下)和付款處理器(信用卡、PayPal、LINE Pay)。用繼承的話,2 x 3 = 6 個 class。再加一種流程?3 x 3 = 9 個。爆炸式增長。
Bridge Pattern 的解法是:把兩個維度拆開,用組合(不是繼承)連接。
先講結論
Bridge 把「抽象」和「實作」分成兩個獨立的層級,各自可以獨立發展。要加新的付款流程?加一個 class。要加新的處理器?也加一個 class。兩邊互不影響。
classDiagram class Payment { <<Abstraction>> -processor : PaymentProcessor +process(amount)* Result } class OnlinePayment { +process(amount) Result } class PaymentProcessor { <<Implementation>> +processPayment(amount)* Result } class CreditCardProcessor { +processPayment(amount) Result } Payment <|-- OnlinePayment PaymentProcessor <|-- CreditCardProcessor Payment o-- PaymentProcessor : 橋接
實戰:付款系統

// 實作層:各種付款處理器
class CreditCardProcessor {
async processPayment(amount) {
console.log(`信用卡處理: $${amount}`);
return { success: true, method: 'credit_card', amount };
}
}
class LinePayProcessor {
async processPayment(amount) {
console.log(`LINE Pay 處理: $${amount}`);
return { success: true, method: 'line_pay', amount };
}
}
// 抽象層:付款流程
class OnlinePayment {
constructor(processor) {
this.processor = processor; // 橋接點
}
async process(amount) {
console.log('線上付款流程啟動...');
return await this.processor.processPayment(amount);
}
}
// 自由組合:線上 + 信用卡、線上 + LINE Pay
const payment1 = new OnlinePayment(new CreditCardProcessor());
const payment2 = new OnlinePayment(new LinePayProcessor());
await payment1.process(100); // 線上 + 信用卡
await payment2.process(200); // 線上 + LINE Pay新增一個 OfflinePayment?寫一個 class,跟任何 Processor 組合都行。新增一個 PayPalProcessor?也是寫一個 class,跟任何 Payment 流程組合都行。
Bridge vs Strategy
兩個都用組合,但意圖不同:
- Bridge:解決「兩個獨立維度的排列組合」問題
- Strategy:解決「同一個維度的演算法替換」問題
如果你只有一個維度在變化,用 Strategy。有兩個以上維度在變化,考慮 Bridge。
Bridge Pattern 就像 USB-C——手機和充電器各自發展,中間只要一個統一的接口就能連起來。問題是你的舊 Micro USB 線還有一百條。