當系統包含多個相互依賴的子系統(如:驗證服務、資料存取、日誌、快取、通知)時,客戶端直接與各子系統交互會導致高耦合、使用複雜、測試困難。外觀模式提供一個統一的高層介面,封裝子系統的複雜交互,讓客戶端只需呼叫單一入口方法。本文以「用戶驗證 + 訊息查詢」為例,展示 Message 外觀類別如何封裝 User.Validate() 與 SqlMessage.Get() 兩個子系統操作。
User(驗證邏輯)、SqlMessage(資料查詢),各自獨立實作單一職責。Message 類別,持有子系統參考,提供 Get() 統一入口,內部協調驗證→查詢流程,處理失敗情況。Message 外觀,不知曉子系統存在。
public class User
{
public bool Validate(string userId)
{
return userId == "admin"; // 簡化:僅 admin 通過
}
}
public class SqlMessage
{
public List<MessageModel> Get()
{
var l = new List<MessageModel>();
l.Add(new MessageModel("SQL方式獲取Message", DateTime.Now));
return l;
}
}
public class Message
{
private string _userId;
public Message(string userId) { this._userId = userId; }
public List<MessageModel> Get()
{
User u = new User();
SqlMessage m = new SqlMessage();
if (u.Validate(_userId))
return m.Get(); // 驗證通過 → 查詢資料
else
{
// 驗證失敗 → 回傳預設訊息
var l = new List<MessageModel>();
l.Add(new MessageModel("無權獲取", DateTime.Now));
return l;
}
}
}
關鍵設計:
userId),內部實例化子系統(或注入)。Get() 封裝「驗證→查詢」固定流程,客戶端單次呼叫完成完整業務。
Message m = new Message("user"); // 非 admin
Response.Write(m.Get()[0].Message); // 輸出:無權獲取
m = new Message("admin"); // admin
Response.Write(m.Get()[0].Message); // 輸出:SQL方式獲取Message
無權獲取 2007-3-20 22:16:50
SQL方式獲取Message 2007-3-20 22:16:50
客戶端零感知子系統複雜性,同一介面根據參數產生不同結果。
| 模式 | 意圖 | 關係 |
|---|---|---|
| 外觀 | 簡化介面,隱藏子系統複雜性 | 單向:外觀→子系統,子系統不知外觀 |
| 中介者 | 協調同事間交互 | 雙向:中介者↔同事,同事知中介者 |
| 代理 | 控制對單一物件存取 | 代理實作同介面,透明替換真實物件 |
| 適配器 | 轉換介面使不相容類別能合作 | 適配器實作目標介面,包裝被適配者 |
public class MessageFacade
{
private readonly IUserService _userService;
private readonly IMessageRepository _messageRepo;
public MessageFacade(IUserService userService, IMessageRepository messageRepo)
{
_userService = userService;
_messageRepo = messageRepo;
}
public List<MessageModel> GetMessages(string userId)
{
if (!_userService.Validate(userId))
return new List<MessageModel> { new MessageModel("無權獲取", DateTime.Now) };
return _messageRepo.GetAll();
}
}
優點:外觀可測試(Mock 子系統)、支援多實現切換、生命週期由容器管理。
DbContext (EF Core)、HttpClient、JsonSerializer。外觀模式以「一個統一介面」化解「複雜子系統」的使用難題。本範例以 Message 封裝 User.Validate() + SqlMessage.Get() 為例,展示了外觀如何將多步驟協調邏輯內部化,為客戶端提供極簡的 Get() 入口。實務中,從資料庫 Context、HTTP Client、序列化器到微服務 Gateway、Application Service,外觀模式是分層架構、模組化設計、第三方庫整合的基石。掌握其核心——「封裝協調、不含業務、非強制唯一、防止膨脹」,能讓你在設計系統邊界、模組介面、遷移策略時,構建出清晰分層、低耦合、易演進的軟體架構。