一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C# - 解析C#設計模式編程中外觀模式Facade Pattern的應用

解析C#設計模式編程中外觀模式Facade Pattern的應用

2021-11-12 15:29田志良 C#

這篇文章主要介紹了C#設計模式編程中外觀模式Facade Pattern的應用,外觀模式中分為門面(Facade)和子系統(subsystem)兩個角色來進行實現,需要的朋友可以參考下

實例引入
在家庭影院中,有燈光,屏幕,投影機,功放機,dvd 播放器這幾個基本的工具:

  • 燈光,可以關閉燈光和打開燈光。
  • 投影機,可以打開和關閉投影機。
  • 屏幕,可以打開和關閉。
  • 功放機,可以關閉音量和打開音量。
  • dvd 播放器,可以打開播放器和關閉播放器。

  以最普通的方式實現觀看電影,類圖如下所示:

解析C#設計模式編程中外觀模式Facade Pattern的應用

按照類圖所示,如果要觀看電影,必須在客戶端執行下面的操作:先打開投影儀,再打開功放機,再打開屏幕,再打開 dvd 播放機,再打開燈光,在經歷了這么多操作后,才可以看一場電影。而在關閉電影的時候,也要先關閉投影儀,再關閉功放機,再關閉屏幕,再關閉 dvd 播放機,再關閉燈光。哦,這是太復雜了!!!在客戶端居然有那么多操作,如果有一些用戶不知道如何使用其中的一個工具,那他便看不了電影!

  上面其實反映的是現今軟件開發系統中的一個比較常見的現象,客戶端程序經常和復雜系統的內部子系統產生直接聯系,導致客戶程序隨著子系統的變化而變化。要想解決上面的這一串問題,必須要簡化客戶程序與子系統之間的交互接口,解除客戶程序和子系統之間的耦合,而外觀模式正好可以解決這個問題。

  外觀模式(facade)的定義:為子系統中的一組接口提供一個一致的界面,用來訪問子系統中的一群接口。

  此模式定義了一個高層的接口,這個接口使得這一子系統更加容易使用。簡單的說,就是外觀模式將一個或者多個類的復雜的操作進行了隱藏,只顯示出一個一致的界面供客戶端使用。需要注意的是,外觀模式僅僅是給你提供了更為直接和容易的操作方式,它并沒有把原來的子系統進行隔離,所以,如果你還需要子系統類的更高層的功能,還是可以使用原來的子系統的,這個是外觀模式的一大優點。通過外觀模式可以將子系統的多個接口上建立一個高層接口,并且將這個高層接口提供給客戶端使用,這樣便可以解除掉客戶端和復雜子系統之間的耦合。

解析C#設計模式編程中外觀模式Facade Pattern的應用

  通過上圖可以看出,外觀模式實現提供簡單的接口(openmovie 和 closemovie)給客戶端,也給客戶端和子系統之間實現了解耦。下面通過代碼來實現上面的這個 demo。

解析C#設計模式編程中外觀模式Facade Pattern的應用

幾個播放工具的代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
using system;
namespace facade
{
  /// <summary>
  /// 投影儀
  /// </summary>
  public class projector
  {
    public void openprojector()
    {
      console.writeline("打開投影儀");
    }
    public void closeprojector()
    {
      console.writeline("關閉投影儀");
    }
    public void setwidescreen()
    {
      console.writeline("投影儀狀態為寬屏模式");
    }
    public void setstandardscreen()
    {
      console.writeline("投影儀狀態為標準模式");
    }
  }
}
     
     
using system;
namespace facade
{
  /// <summary>
  /// 功放機
  /// </summary>
  public class amplifier
  {
    public void openamplifier()
    {
      console.writeline("打開功放機");
    }
    public void closeamplifier()
    {
      console.writeline("關閉功放機");
    }
  }
}
       
        
using system;
namespace facade
{
  /// <summary>
  /// 屏幕
  /// </summary>
  public class screen
  {
    public void openscreen()
    {
      console.writeline("打開屏幕");
    }
    public void closescreen()
    {
      console.writeline("關閉屏幕");
    }
  }
}
        
        
using system;
namespace facade
{
  /// <summary>
  /// dvd播放器
  /// </summary>
  public class dvdplayer
  {
    public void opendvdplayer()
    {
      console.writeline("打開 dvd 播放器");
    }
    public void closedvdplayer()
    {
      console.writeline("關閉 dvd 播放器");
    }
  }
}
        
       
using system;
namespace facade
{
  /// <summary>
  /// 燈光
  /// </summary>
  public class light
  {
    public void openlight()
    {
      console.writeline("打開燈光");
    }
    public void closelight()
    {
      console.writeline("關閉燈光");
    }
  }
}

  外觀類中的代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
namespace facade
{
  /// <summary>
  /// 定義一個外觀
  /// </summary>
  public class moviefacade
  {
    /// <summary>
    /// 在外觀類中必須保存有子系統中各個對象
    /// </summary>
    private projector projector;
    private amplifier amplifier;
    private screen screen;
    private dvdplayer dvdplayer;
    private light light;
    public moviefacade()
    {
      projector = new projector();
      amplifier = new amplifier();
      screen = new screen();
      dvdplayer = new dvdplayer();
      light = new light();
    }
    /// <summary>
    /// 打開電影
    /// </summary>
    public void openmovie()
    {
      //先打開投影儀
      projector.openprojector();
      //再打開功放
      amplifier.openamplifier();
      //再打開屏幕
      screen.openscreen();
      //再打開 dvd
      dvdplayer.opendvdplayer();
      //再打開燈光
      light.openlight();
    }
    /// <summary>
    /// 關閉電影
    /// </summary>
    public void closemovie()
    {
      //關閉投影儀
      projector.closeprojector();
      //關閉功放
      amplifier.closeamplifier();
      //關閉屏幕
      screen.closescreen();
      //關閉 dvd
      dvdplayer.closedvdplayer();
      //關閉燈光
      light.closelight();
    }
  }
}

  客戶端代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using system;
namespace facadetest
{
  class program
  {
    static void main(string[] args)
    {
      facade.moviefacade movie = new facade.moviefacade();
      facade.projector projector = new facade.projector();
        
      //首先是觀看電影
      movie.openmovie();
      console.writeline();
       
      //然后是將投影儀模式調到寬屏模式
      projector.setwidescreen();
      //再將投影儀模式調回普通模式
      projector.setstandardscreen();
      console.writeline();
      
      //最后就是關閉電影了
      movie.closemovie();
      console.readkey();
    }
  }
}

  從上例中可以看出,可以在客戶端中使用子系統中的內容,即外觀模式并沒有把子系統和客戶端隔離開來,只是提供了整潔的接口給客戶端,如果客戶端想訪問復雜子系統中的接口時還是一樣的可以訪問的。比如在上面的 demo 中的設置了寬屏和普通等模式。

外觀模式的結構總結
看完外觀模式的實現之后,為了幫助理清外觀模式中類之間的關系,下面給出上面實現代碼中類圖:

解析C#設計模式編程中外觀模式Facade Pattern的應用

然而對于外觀模式而言,是沒有一個一般化的類圖描述,下面演示一個外觀模式的示意性對象圖來加深大家對外觀模式的理解:

解析C#設計模式編程中外觀模式Facade Pattern的應用

在上面的對象圖中有兩個角色:

門面(facade)角色:客戶端調用這個角色的方法。該角色知道相關的一個或多個子系統的功能和責任,該角色會將從客戶端發來的請求委派帶相應的子系統中去。

子系統(subsystem)角色:可以同時包含一個或多個子系統。每個子系統都不是一個單獨的類,而是一個類的集合。每個子系統都可以被客戶端直接調用或被門面角色調用。對于子系統而言,門面僅僅是另外一個客戶端,子系統并不知道門面的存在。

外觀的優缺點
優點:

外觀模式對客戶屏蔽了子系統組件,從而簡化了接口,減少了客戶處理的對象數目并使子系統的使用更加簡單。
外觀模式實現了子系統與客戶之間的松耦合關系,而子系統內部的功能組件是緊耦合的。松耦合使得子系統的組件變化不會影響到它的客戶。
缺點:

如果增加新的子系統可能需要修改外觀類或客戶端的源代碼,這樣就違背了”開——閉原則“(不過這點也是不可避免)。


使用場景
在以下情況下可以考慮使用外觀模式:

外一個復雜的子系統提供一個簡單的接口
提供子系統的獨立性
在層次化結構中,可以使用外觀模式定義系統中每一層的入口。其中三層架構就是這樣的一個例子。

 

總結
到這里外觀模式的介紹就結束了,外觀模式,為子系統的一組接口提供一個統一的接口,該模式定義了一個高層接口,這一個高層接口使的子系統更加容易使用。并且外觀模式可以解決層結構分離、降低系統耦合度和為新舊系統交互提供接口功能。

延伸 · 閱讀

精彩推薦
  • C#C#通過KD樹進行距離最近點的查找

    C#通過KD樹進行距離最近點的查找

    這篇文章主要為大家詳細介紹了C#通過KD樹進行距離最近點的查找,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    帆帆帆6112022-01-22
  • C#C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題實例

    C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題實例

    這篇文章主要介紹了C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題,簡單描述了訪問者模式的定義并結合具體實例形式分析了C#使用訪問者模式解決長...

    GhostRider9502022-01-21
  • C#WPF 自定義雷達圖開發實例教程

    WPF 自定義雷達圖開發實例教程

    這篇文章主要介紹了WPF 自定義雷達圖開發實例教程,本文介紹的非常詳細,具有參考借鑒價值,需要的朋友可以參考下...

    WinterFish13112021-12-06
  • C#C#實現XML文件讀取

    C#實現XML文件讀取

    這篇文章主要為大家詳細介紹了C#實現XML文件讀取的相關代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    Just_for_Myself6702022-02-22
  • C#Unity3D實現虛擬按鈕控制人物移動效果

    Unity3D實現虛擬按鈕控制人物移動效果

    這篇文章主要為大家詳細介紹了Unity3D實現虛擬按鈕控制人物移動效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一...

    shenqingyu060520232410972022-03-11
  • C#C#裁剪,縮放,清晰度,水印處理操作示例

    C#裁剪,縮放,清晰度,水印處理操作示例

    這篇文章主要為大家詳細介紹了C#裁剪,縮放,清晰度,水印處理操作示例,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    吳 劍8332021-12-08
  • C#C# 實現對PPT文檔加密、解密及重置密碼的操作方法

    C# 實現對PPT文檔加密、解密及重置密碼的操作方法

    這篇文章主要介紹了C# 實現對PPT文檔加密、解密及重置密碼的操作方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下...

    E-iceblue5012022-02-12
  • C#深入解析C#中的交錯數組與隱式類型的數組

    深入解析C#中的交錯數組與隱式類型的數組

    這篇文章主要介紹了深入解析C#中的交錯數組與隱式類型的數組,隱式類型的數組通常與匿名類型以及對象初始值設定項和集合初始值設定項一起使用,需要的...

    C#教程網6172021-11-09
主站蜘蛛池模板: 国产青草亚洲香蕉精品久久 | 国产精品区牛牛影院 | 2019自拍偷拍视频 | 亚洲一区二区日韩欧美gif | 日韩二区三区 | 热伊人99re久久精品最新地 | 男男gaygays中国 | 嫩草成人国产精品 | 成全动漫视频在线观看 | 500第一精品| 亚洲ss | 国产成人夜色91 | av在线亚洲男人的天堂 | 法国女佣系列在线播放 | 91制片厂制作果冻传媒八夷 | 521色香蕉网在线观看免费 | 成人影院观看 | 久久国内精品 | 成年人视频免费在线播放 | 国产全部理论片线观看 | 插得好爽| 欧美免赞性视频 | 成年男女免费视频网站 | 国产精品青青青高清在线密亚 | 国产精品香蕉在线观看不卡 | 国产欧美又粗又猛又爽老 | 俄罗斯美女大逼 | avtt天堂网手机版亚洲 | 天天久久综合网站 | 娇女的呻吟亲女禁忌h16 | 鸭子玩富婆流白浆视频 | 爱欲荡漾在线观看 | 四虎最新永久在线精品免费 | 四虎影院4hu | 九九九九九热 | 日本一区二区三区在线 观看网站 | 加勒比一本大道在线 | 青青青视频免费观看 | 微福利92合集 | 免费国产在线观看 | 青草视频在线观看免费视频 |