博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(原創) 我的Design Pattern之旅[5]:Facade Pattern (OO) (Design Pattern) (C/C++)
阅读量:6037 次
发布时间:2019-06-20

本文共 3296 字,大约阅读时间需要 10 分钟。

Abstract

facade是我學到的第三個pattern,也是個很簡單的pattern,主要是將眾多class重新包裝成一個更好用的class。
Intent
替子系統裡的一堆介面定義一套統一的高階介面,讓子系統更易使用。
Introduction
Facade常用在兩個地方,第一種用法是將原來程序導向的系統,利用Facade包成OO,如MFC包裝Win32 API,第二種用法是將原來複雜的OO系統,再包成更簡單的OO,如.NET Enterprise Library將.NET Framework再做一次包裝,讓你更容易使用.NET。另外3-tier也是典型Facade的應用,DAL(Data Access Layer)就是一個Facade,讓BLL(Business Logic Layer)在存取資料時,不用對付ADO.NET複雜的機制,只需面對DAL即可。
Sample Code
如我們坐捷運買票,目前的賣票的機器只能吃銅板,所以得另外的提供換鈔機,讓旅客將紙幣換成銅板,也就是說,若一個旅客身上只有紙幣又要賣捷運票,他必須做兩個步驟,先將紙幣換成銅板,再用銅板去買車票。

 1
ExpandedBlockStart.gif
ContractedBlock.gif
/**/
/* 
 2(C) OOMusou 2007 http://oomusou.cnblogs.com
 3
 4Filename    : DP_FacadePattern1_before.cpp
 5Compiler    : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++
 6Description : Demo how to use Facade pattern (before)
 7Release     : 04/24/2007 1.0
 8*/
 9
#include 
<
iostream
>
10
11
using
 
namespace
 std;
12
13
ExpandedBlockStart.gifContractedBlock.gif
struct
 Bill 
{
14  int value;
15ExpandedSubBlockStart.gifContractedSubBlock.gif  Bill(int value) : value(value) {}
16}
;
17
18
ExpandedBlockStart.gifContractedBlock.gif
struct
 Coin 
{
19  int value;
20ExpandedSubBlockStart.gifContractedSubBlock.gif  Coin(int value) : value(value) {}
21}
;
22
23
ExpandedBlockStart.gifContractedBlock.gif
class
 BillToCoinMachine 
{
24public:
25ExpandedSubBlockStart.gifContractedSubBlock.gif  Coin getCoin(Bill bill) {
26    return Coin(10);
27  }
28}
;
29
30
ExpandedBlockStart.gifContractedBlock.gif
class
 CoinToTicketMachine 
{
31public:
32ExpandedSubBlockStart.gifContractedSubBlock.gif  void getTicket(Coin coin) {
33    cout << "Get ticket" << endl;
34  }
35}
;
36
37
ExpandedBlockStart.gifContractedBlock.gif
int
 main() 
{
38  BillToCoinMachine machine1;
39  Coin coin = machine1.getCoin(Bill(100));
40  
41  CoinToTicketMachine machine2;
42  machine2.getTicket(coin);
43}

執行結果

Get ticket
但對於旅客來說,似乎太嫌麻煩,買個票要排兩次隊,若我們能設計一部機器,能吃紙鈔,且能購票,那對旅客將非常的方便。事實上,我們並不需重新設計這樣的機器,只要將這兩台機器整合成一台即可。
 1
ExpandedBlockStart.gif
ContractedBlock.gif
/**/
/* 
 2(C) OOMusou 2007 http://oomusou.cnblogs.com
 3
 4Filename    : DP_FacadePattern1_after.cpp
 5Compiler    : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++
 6Description : Demo how to use Facade pattern (after)
 7Release     : 04/24/2007 1.0
 8*/
 9
#include 
<
iostream
>
10
11
using
 
namespace
 std;
12
13
ExpandedBlockStart.gifContractedBlock.gif
struct
 Bill 
{
14  int value;
15ExpandedSubBlockStart.gifContractedSubBlock.gif  Bill(int value) : value(value) {}
16}
;
17
18
ExpandedBlockStart.gifContractedBlock.gif
struct
 Coin 
{
19  int value;
20ExpandedSubBlockStart.gifContractedSubBlock.gif  Coin(int value) : value(value) {}
21}
;
22
23
ExpandedBlockStart.gifContractedBlock.gif
class
 BillToCoinMachine 
{
24public:
25ExpandedSubBlockStart.gifContractedSubBlock.gif  Coin getCoin(Bill bill) {
26    return Coin(10);
27  }
28}
;
29
30
ExpandedBlockStart.gifContractedBlock.gif
class
 CoinToTicketMachine 
{
31public:
32ExpandedSubBlockStart.gifContractedSubBlock.gif  void getTicket(Coin coin) {
33    cout << "Get ticket" << endl;
34  }
35}
;
36
37
ExpandedBlockStart.gifContractedBlock.gif
class
 TicketMachineFacade 
{
38public:
39ExpandedSubBlockStart.gifContractedSubBlock.gif  void coinToTicket(Coin coin) {
40    CoinToTicketMachine machine;
41    machine.getTicket(coin);
42  }
43  
44ExpandedSubBlockStart.gifContractedSubBlock.gif  void billToTicket(Bill bill) {
45    BillToCoinMachine machine1;
46    Coin coin = machine1.getCoin(bill);
47    
48    CoinToTicketMachine machine2;
49    machine2.getTicket(coin);
50  }
51}
;
52
53
ExpandedBlockStart.gifContractedBlock.gif
int
 main() 
{
54  TicketMachineFacade TMFacade;
55  TMFacade.billToTicket(Bill(100));
56  TMFacade.coinToTicket(Coin(10));
57}

執行結果

1
Get ticket
2
Get ticket

可以看到client的程式明顯乾淨多了

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

這表示旅客可以用更簡單的方式買票了。
Consequence
1.避免外界觸及子系統的元件,降低外界所要面對的物件數量,讓子系統更容易使用。
2.促成外界與子系統之間的低偶合性。在子系統裡,元件之間的耦合性往往都很高,降低耦合性會使原件更容易改變而不波及外界。Facade有助於將系統分層、將物件之間的依存關係分層,順便剔除複雜的、循環的依存關係;這對於需要將client和子系統分開製作的專案而言,是非常重要的性質。
對大型軟體系統來說,降低編譯方面的依存關係是非常重要的;子系統一有變動,大家都希望重新編譯的時間能越短越好。只要用Facade降低編譯依存關係,不僅能將重新編譯的動作侷限在一小塊區域,更有利於軟體移植:只是重新編譯一塊子系統,不太需要其他地方也一起再編譯一遍。
3.如有必要,外界仍可直接接觸子系統內的類別,所以你可以在易用性與一般性之間做選擇。
Conclusion
或許你會覺得facade pattern沒什麼,的確,他只是一個概念而已,而且非常單純,但卻常常看的到。
Known use
1..NET Enterprise Library的DAAB
2..NET 2.0的My
3.網路架構的OSI模型

See Also

Reference

GoF,Design Patterns,Addison Weseley ,1995

你可能感兴趣的文章
Linux signal 那些事儿(2)【转】
查看>>
InfluxDB安装及配置
查看>>
Dynamics CRM Microsoft SQL Server 指定的数据库具有更高的版本号
查看>>
PAT Perfect Sequence (25)
查看>>
java.exe进程来源排查录
查看>>
点滴记录——Ubuntu 14.04中Solr与Tomcat整合安装
查看>>
C++实现KMP模式匹配算法
查看>>
ubuntu linux下建立stm32开发环境: GCC安装以及工程Makefile建立
查看>>
记录锁
查看>>
JSONObject与JSONArray的使用
查看>>
[SQL Server] 数据库日志文件自动增长导致连接超时的分析
查看>>
【常见Web应用安全问题】---6、Script source code disclosure
查看>>
<html:form>标签
查看>>
除了《一无所有》,我一无所有
查看>>
每日英语:China Seeks to Calm Anxiety Over Rice
查看>>
C++中struct和class的区别 [转]
查看>>
C++ ofstream和ifstream详细用法
查看>>
【G-BLASTN 1.0正式发布】
查看>>
Mysql 连接查询 Mysql支持的连接查询有哪些
查看>>
《ASP.NET1200例》<asp:DataList>分页显示图片
查看>>