多通路電商系統架構:用工廠模式整合 17 個平台

商業價值:這篇介紹的工廠模式讓「新增平台從 2-3 個月縮短到 2-3 週」,直接影響 導讀篇提到的 80% 擴展成本降低

前言:當你要同時對接 17 個電商平台

在多通路電商系統中,我們需要整合多個平台:

平台類型 範例 特性
綜合電商 蝦皮、Momo、Yahoo、PChome 訂單量大、API 複雜
開店平台 Shopify、Shopline、91APP 彈性高、客製化多
國際平台 樂天、Coupang、Amazon 多語系、跨境物流
問題:每個平台的 API 格式、認證方式、資料結構都不同。如果用 if-else 判斷,程式碼會變成災難。

解決方案:工廠模式 + 策略模式

核心思想:定義統一介面,每個平台各自實作。新增平台時,只需要新增一個實作類別。

Step 1:定義統一介面

所有平台都必須實作這個介面:

/**
* 電商平台動作介面
* 所有平台整合都必須實作這個介面
*/

public interface ChannelAction {

// 取得平台設定(API URL、版本等)
ChannelSetting getSetting();

// 取得平台授權 Token
TokenResult getAccessToken(Merchant merchant);

// 驗證必要資料是否齊全
boolean validateRequired(ActionRequest request);

// 執行實際動作(同步訂單、更新庫存等)
ActionResult execute(ActionRequest request);
}

Step 2:每個平台各自實作

蝦皮實作範例:

@Component
public class ShopeeAction implements ChannelAction {

@Override
public ChannelSetting getSetting() {
return ChannelSetting.builder()
.apiUrl(“https://partner.shopeemobile.com”)
.version(“v2”)
.authType(AuthType.OAUTH2)
.build();
}

@Override
public TokenResult getAccessToken(Merchant merchant) {
// 蝦皮使用 OAuth2 + 簽章驗證
String signature = generateSignature(merchant);
return callShopeeAuthAPI(merchant, signature);
}

@Override
public ActionResult execute(ActionRequest request) {
// 呼叫蝦皮 API 執行動作
return callShopeeAPI(request);
}
}

Momo 實作範例:

@Component
public class MomoAction implements ChannelAction {

@Override
public ChannelSetting getSetting() {
return ChannelSetting.builder()
.apiUrl(“https://api.momo.com.tw”)
.version(“v1”)
.authType(AuthType.API_KEY)
.build();
}

@Override
public TokenResult getAccessToken(Merchant merchant) {
// Momo 使用 API Key 驗證
return TokenResult.of(merchant.getMomoApiKey());
}

@Override
public ActionResult execute(ActionRequest request) {
// 呼叫 Momo API 執行動作
return callMomoAPI(request);
}
}

Step 3:工廠類別統一管理

@Component
public class ChannelFactory {

private final Map<ChannelType, ChannelAction> actionMap;

// Spring 自動注入所有 ChannelAction 實作
public ChannelFactory(List<ChannelAction> actions) {
this.actionMap = actions.stream()
.collect(Collectors.toMap(
action -> action.getSetting().getChannelType(),
action -> action
));
}

/**
* 根據通路類型取得對應的實作
*/

public ChannelAction getAction(ChannelType channelType) {
ChannelAction action = actionMap.get(channelType);
if (action == null) {
throw new UnsupportedChannelException(
“不支援的通路: “ + channelType
);
}
return action;
}
}


使用方式

業務邏輯層只需要這樣呼叫:

@Service
public class OrderSyncService {

@Autowired
private ChannelFactory channelFactory;

public SyncResult syncOrders(ChannelType channel, Merchant merchant) {
// 1. 取得對應的通路實作
ChannelAction action = channelFactory.getAction(channel);

// 2. 取得授權 Token
TokenResult token = action.getAccessToken(merchant);

// 3. 執行同步
ActionRequest request = ActionRequest.builder()
.merchant(merchant)
.token(token)
.actionType(ActionType.SYNC_ORDERS)
.build();

return action.execute(request);
}
}

優點:不管是蝦皮、Momo、Yahoo 還是其他平台,呼叫方式完全一樣。新增平台時,業務邏輯層完全不用改。

新增平台有多簡單?

假設要新增 Coupang 韓國平台:

@Component
public class CoupangAction implements ChannelAction {

@Override
public ChannelSetting getSetting() {
return ChannelSetting.builder()
.apiUrl(“https://api-gateway.coupang.com”)
.version(“v2”)
.authType(AuthType.HMAC)
.build();
}

// … 實作其他方法
}

步驟 工作內容 影響範圍
1 建立 CoupangAction 類別 只有新檔案
2 實作 ChannelAction 介面 只有新檔案
3 加上 @Component 註解 只有新檔案
4 完成!Spring 自動註冊 零修改現有程式

設計模式總結

模式 用途 在這裡的應用
策略模式 定義演算法家族,讓它們可互換 每個平台是一個策略
工廠模式 封裝物件建立邏輯 根據通路類型取得實作
依賴注入 解耦合 Spring 自動管理
效益:

  • 新增通路:從 2-3 個月縮短到 2-3 週
  • 維護成本:改一個平台不影響其他平台
  • 測試:每個平台可以獨立單元測試

為什麼不用其他方案?

方案 優點 缺點 結論
if-else 判斷 簡單直接 每次加平台要改核心程式碼 小規模可用,超過 3 個平台就很痛苦
Switch Case 比 if-else 清楚 還是要改核心程式碼 同上
反射 + 設定檔 完全不改程式碼 除錯困難、IDE 無法追蹤 過度設計,維護成本高
工廠 + 策略 新增只加檔案、Spring 自動註冊 需要理解設計模式 中大型系統的最佳平衡

實戰踩坑

坑 1:平台 API 變更沒通知

蝦皮某次 API 升級,回傳欄位名稱從 order_sn 改成 ordersn。因為每個平台有獨立的 Action 類別,我們只需要改 ShopeeAction,其他 16 個平台完全不受影響。如果用 if-else,改錯一行就全部爆炸。

坑 2:忘記加 @Component

新人寫好 CoupangAction 卻沒加 @Component,Spring 沒註冊到 Factory。呼叫時直接噴 UnsupportedChannelException。後來在程式碼審查加入檢查項:「確認新 Action 有 @Component」。

坑 3:介面設計太死

最初 ChannelAction 只有 execute() 一個方法。後來發現有些平台需要 OAuth 刷新 Token、有些需要 Webhook 處理。介面改了三次才穩定。教訓:先做 3-5 個平台再抽象,別一開始就過度設計


系列導航

◀ 上一篇
導讀篇
📚 返回目錄 下一篇 ▶
Kafka 事件驅動

留言

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *