首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

設計模式之旅:外觀模式深度解析與實戰應用

     編輯:關於C#

意圖

為子系統中的一組介面提供一個統一的高層介面,使子系統更容易被使用。

引言

外觀模式常見於兩類場景:

  1. 將面向過程的系統包裝為物件導向系統,例如 MFC 封裝 Win32 API。
  2. 將複雜的物件導向系統再次封裝為更簡單的介面,例如 .NET Enterprise Library 對 .NET Framework 的二次封裝。

三層架構也是典型的外觀模式應用:資料存取層 (DAL) 即為一個外觀,讓業務邏輯層 (BLL) 在存取資料時無需直接面對 ADO.NET 的複雜機制,只需與 DAL 互動即可。

範例程式碼:捷運買票系統

假設捷運售票機只接受硬幣,乘客若只有紙鈔,必須先到換鈔機換成硬幣,再到售票機買票,需排兩次隊,過程繁瑣。

購票前流程圖

引入外觀模式前

/**/*
 (C) OOMusou 2007 https://oomusou.cnblogs.com

Filename : DP_FacadePattern1_before.cpp
Compiler : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++
Description : Demo how to use Facade pattern (before)
Release : 04/24/2007 1.0
*/
#include <iostream>

using namespace std;

struct Bill {
 int value;
 Bill(int value) : value(value) {}
};

struct Coin {
 int value;
 Coin(int value) : value(value) {}
};

class BillToCoinMachine {
public:
 Coin getCoin(Bill bill) {
 return Coin(10);
 }
};

class CoinToTicketMachine {
public:
 void getTicket(Coin coin) {
 cout << "Get ticket" << endl;
 }
};

int main() {
 BillToCoinMachine machine1;
 Coin coin = machine1.getCoin(Bill(100));

 CoinToTicketMachine machine2;
 machine2.getTicket(coin);
}

執行結果:

Get ticket

引入外觀模式後

我們設計一台整合機器,直接接受紙鈔並出票,對乘客更友好。實際上不需重新設計硬體,只需將兩台機器整合即可。

購票後流程圖
/**/*
 (C) OOMusou 2007 https://oomusou.cnblogs.com

Filename : DP_FacadePattern1_after.cpp
Compiler : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++
Description : Demo how to use Facade pattern (after)
Release : 04/24/2007 1.0
*/
#include <iostream>

using namespace std;

struct Bill {
 int value;
 Bill(int value) : value(value) {}
};

struct Coin {
 int value;
 Coin(int value) : value(value) {}
};

class BillToCoinMachine {
public:
 Coin getCoin(Bill bill) {
 return Coin(10);
 }
};

class CoinToTicketMachine {
public:
 void getTicket(Coin coin) {
 cout << "Get ticket" << endl;
 }
};

class TicketMachineFacade {
public:
 void coinToTicket(Coin coin) {
 CoinToTicketMachine machine;
 machine.getTicket(coin);
 }

 void billToTicket(Bill bill) {
 BillToCoinMachine machine1;
 Coin coin = machine1.getCoin(bill);

 CoinToTicketMachine machine2;
 machine2.getTicket(coin);
 }
};

int main() {
 TicketMachineFacade TMFacade;
 TMFacade.billToTicket(Bill(100));
 TMFacade.coinToTicket(Coin(10));
}

執行結果:

Get ticket
Get ticket

客戶端程式碼變得乾淨許多:

int main() {
 TicketMachineFacade TMFacade;
 TMFacade.billToTicket(Bill(100));
 TMFacade.coinToTicket(Coin(10));
}

這表示旅客可以用更簡單的方式買票了。

後果與優勢

  1. 隔離子系統元件:避免外界直接觸及子系統內部元件,降低外界需面對的物件數量,使子系統更易使用。
  2. 促進低耦合:子系統內部元件往往高度耦合,外觀模式有助於將系統分層、將依賴關係分層,剔除複雜的循環依賴。這對客戶端與子系統分開開發的專案至關重要。對大型系統而言,降低編譯依賴能縮短重新編譯時間,利於軟體移植。
  3. 保留彈性:如有必要,外界仍可直接存取子系統內部類別,在易用性與通用性之間取得平衡。

結語

外觀模式或許看似單純,只是一個概念,但它在實務中極為常見。

已知應用

  1. .NET Enterprise Library 的 DAAB
  2. .NET 2.0 的 My 命名空間
  3. 網路架構的 OSI 模型
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved