欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

解析C#設(shè)計(jì)模式編程中外觀模式Facade Pattern的應(yīng)用

 更新時(shí)間:2016年02月19日 09:45:24   作者:田志良  
這篇文章主要介紹了C#設(shè)計(jì)模式編程中外觀模式Facade Pattern的應(yīng)用,外觀模式中分為門(mén)面(Facade)和子系統(tǒng)(subsystem)兩個(gè)角色來(lái)進(jìn)行實(shí)現(xiàn),需要的朋友可以參考下

實(shí)例引入
在家庭影院中,有燈光,屏幕,投影機(jī),功放機(jī),DVD 播放器這幾個(gè)基本的工具:

  • 燈光,可以關(guān)閉燈光和打開(kāi)燈光。
  • 投影機(jī),可以打開(kāi)和關(guān)閉投影機(jī)。
  • 屏幕,可以打開(kāi)和關(guān)閉。
  • 功放機(jī),可以關(guān)閉音量和打開(kāi)音量。
  • DVD 播放器,可以打開(kāi)播放器和關(guān)閉播放器。

  以最普通的方式實(shí)現(xiàn)觀看電影,類(lèi)圖如下所示:

201621994222971.jpg (640×309)

按照類(lèi)圖所示,如果要觀看電影,必須在客戶端執(zhí)行下面的操作:先打開(kāi)投影儀,再打開(kāi)功放機(jī),再打開(kāi)屏幕,再打開(kāi) DVD 播放機(jī),再打開(kāi)燈光,在經(jīng)歷了這么多操作后,才可以看一場(chǎng)電影。而在關(guān)閉電影的時(shí)候,也要先關(guān)閉投影儀,再關(guān)閉功放機(jī),再關(guān)閉屏幕,再關(guān)閉 DVD 播放機(jī),再關(guān)閉燈光。哦,這是太復(fù)雜了?。?!在客戶端居然有那么多操作,如果有一些用戶不知道如何使用其中的一個(gè)工具,那他便看不了電影!

  上面其實(shí)反映的是現(xiàn)今軟件開(kāi)發(fā)系統(tǒng)中的一個(gè)比較常見(jiàn)的現(xiàn)象,客戶端程序經(jīng)常和復(fù)雜系統(tǒng)的內(nèi)部子系統(tǒng)產(chǎn)生直接聯(lián)系,導(dǎo)致客戶程序隨著子系統(tǒng)的變化而變化。要想解決上面的這一串問(wèn)題,必須要簡(jiǎn)化客戶程序與子系統(tǒng)之間的交互接口,解除客戶程序和子系統(tǒng)之間的耦合,而外觀模式正好可以解決這個(gè)問(wèn)題。

  外觀模式(Facade)的定義:為子系統(tǒng)中的一組接口提供一個(gè)一致的界面,用來(lái)訪問(wèn)子系統(tǒng)中的一群接口。

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

201621994349141.jpg (685×401)

  通過(guò)上圖可以看出,外觀模式實(shí)現(xiàn)提供簡(jiǎn)單的接口(OpenMovie 和 CloseMovie)給客戶端,也給客戶端和子系統(tǒng)之間實(shí)現(xiàn)了解耦。下面通過(guò)代碼來(lái)實(shí)現(xiàn)上面的這個(gè) Demo。

201621994410364.jpg (738×423)

幾個(gè)播放工具的代碼:

using System;
namespace Facade 
{ 
  /// <summary> 
  /// 投影儀 
  /// </summary> 
  public class Projector 
  { 
    public void OpenProjector() 
    { 
      Console.WriteLine("打開(kāi)投影儀"); 
    }
    public void CloseProjector() 
    { 
      Console.WriteLine("關(guān)閉投影儀"); 
    }
    public void SetWideScreen() 
    { 
      Console.WriteLine("投影儀狀態(tài)為寬屏模式"); 
    }
    public void SetStandardScreen() 
    { 
      Console.WriteLine("投影儀狀態(tài)為標(biāo)準(zhǔn)模式"); 
    } 
  } 
}
     
     
using System;
namespace Facade 
{ 
  /// <summary> 
  /// 功放機(jī) 
  /// </summary> 
  public class Amplifier 
  { 
    public void OpenAmplifier() 
    { 
      Console.WriteLine("打開(kāi)功放機(jī)"); 
    }
    public void CloseAmplifier() 
    { 
      Console.WriteLine("關(guān)閉功放機(jī)"); 
    } 
  } 
}
       
        
using System;
namespace Facade 
{ 
  /// <summary> 
  /// 屏幕 
  /// </summary> 
  public class Screen 
  { 
    public void OpenScreen() 
    { 
      Console.WriteLine("打開(kāi)屏幕"); 
    }
    public void CloseScreen() 
    { 
      Console.WriteLine("關(guān)閉屏幕"); 
    } 
  } 
}
        
        
using System;
namespace Facade 
{ 
  /// <summary> 
  /// DVD播放器 
  /// </summary> 
  public class DVDPlayer 
  { 
    public void OpenDVDPlayer() 
    { 
      Console.WriteLine("打開(kāi) DVD 播放器"); 
    }
    public void CloseDVDPlayer() 
    { 
      Console.WriteLine("關(guān)閉 DVD 播放器"); 
    } 
  } 
}
        
       
using System;
namespace Facade 
{ 
  /// <summary> 
  /// 燈光 
  /// </summary> 
  public class Light 
  { 
    public void OpenLight() 
    { 
      Console.WriteLine("打開(kāi)燈光"); 
    }
    public void CloseLight() 
    { 
      Console.WriteLine("關(guān)閉燈光"); 
    } 
  } 
}

  外觀類(lèi)中的代碼:

namespace Facade 
{ 
  /// <summary> 
  /// 定義一個(gè)外觀 
  /// </summary> 
  public class MovieFacade 
  { 
    /// <summary> 
    /// 在外觀類(lèi)中必須保存有子系統(tǒng)中各個(gè)對(duì)象 
    /// </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> 
    /// 打開(kāi)電影 
    /// </summary> 
    public void OpenMovie() 
    { 
      //先打開(kāi)投影儀 
      projector.OpenProjector(); 
      //再打開(kāi)功放 
      amplifier.OpenAmplifier(); 
      //再打開(kāi)屏幕 
      screen.OpenScreen(); 
      //再打開(kāi) DVD 
      dvdPlayer.OpenDVDPlayer(); 
      //再打開(kāi)燈光 
      light.OpenLight(); 
    }
    /// <summary> 
    /// 關(guān)閉電影 
    /// </summary> 
    public void CloseMovie() 
    { 
      //關(guān)閉投影儀 
      projector.CloseProjector(); 
      //關(guān)閉功放 
      amplifier.CloseAmplifier(); 
      //關(guān)閉屏幕 
      screen.CloseScreen(); 
      //關(guān)閉 DVD 
      dvdPlayer.CloseDVDPlayer(); 
      //關(guān)閉燈光 
      light.CloseLight(); 
    } 
  } 
}

  客戶端代碼:

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();
       
      //然后是將投影儀模式調(diào)到寬屏模式 
      projector.SetWideScreen(); 
      //再將投影儀模式調(diào)回普通模式 
      projector.SetStandardScreen(); 
      Console.WriteLine();
      
      //最后就是關(guān)閉電影了 
      movie.CloseMovie();
      Console.ReadKey(); 
    } 
  } 
}

  從上例中可以看出,可以在客戶端中使用子系統(tǒng)中的內(nèi)容,即外觀模式并沒(méi)有把子系統(tǒng)和客戶端隔離開(kāi)來(lái),只是提供了整潔的接口給客戶端,如果客戶端想訪問(wèn)復(fù)雜子系統(tǒng)中的接口時(shí)還是一樣的可以訪問(wèn)的。比如在上面的 Demo 中的設(shè)置了寬屏和普通等模式。

外觀模式的結(jié)構(gòu)總結(jié)
看完外觀模式的實(shí)現(xiàn)之后,為了幫助理清外觀模式中類(lèi)之間的關(guān)系,下面給出上面實(shí)現(xiàn)代碼中類(lèi)圖:

201621994508122.png (626×363)

然而對(duì)于外觀模式而言,是沒(méi)有一個(gè)一般化的類(lèi)圖描述,下面演示一個(gè)外觀模式的示意性對(duì)象圖來(lái)加深大家對(duì)外觀模式的理解:

201621994528100.png (433×292)

在上面的對(duì)象圖中有兩個(gè)角色:

門(mén)面(Facade)角色:客戶端調(diào)用這個(gè)角色的方法。該角色知道相關(guān)的一個(gè)或多個(gè)子系統(tǒng)的功能和責(zé)任,該角色會(huì)將從客戶端發(fā)來(lái)的請(qǐng)求委派帶相應(yīng)的子系統(tǒng)中去。

子系統(tǒng)(subsystem)角色:可以同時(shí)包含一個(gè)或多個(gè)子系統(tǒng)。每個(gè)子系統(tǒng)都不是一個(gè)單獨(dú)的類(lèi),而是一個(gè)類(lèi)的集合。每個(gè)子系統(tǒng)都可以被客戶端直接調(diào)用或被門(mén)面角色調(diào)用。對(duì)于子系統(tǒng)而言,門(mén)面僅僅是另外一個(gè)客戶端,子系統(tǒng)并不知道門(mén)面的存在。

外觀的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):

外觀模式對(duì)客戶屏蔽了子系統(tǒng)組件,從而簡(jiǎn)化了接口,減少了客戶處理的對(duì)象數(shù)目并使子系統(tǒng)的使用更加簡(jiǎn)單。
外觀模式實(shí)現(xiàn)了子系統(tǒng)與客戶之間的松耦合關(guān)系,而子系統(tǒng)內(nèi)部的功能組件是緊耦合的。松耦合使得子系統(tǒng)的組件變化不會(huì)影響到它的客戶。
缺點(diǎn):

如果增加新的子系統(tǒng)可能需要修改外觀類(lèi)或客戶端的源代碼,這樣就違背了”開(kāi)——閉原則“(不過(guò)這點(diǎn)也是不可避免)。


使用場(chǎng)景
在以下情況下可以考慮使用外觀模式:

外一個(gè)復(fù)雜的子系統(tǒng)提供一個(gè)簡(jiǎn)單的接口
提供子系統(tǒng)的獨(dú)立性
在層次化結(jié)構(gòu)中,可以使用外觀模式定義系統(tǒng)中每一層的入口。其中三層架構(gòu)就是這樣的一個(gè)例子。

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

相關(guān)文章

最新評(píng)論