1. 程式人生 > >設計模式(15)-Facade Pattern

設計模式(15)-Facade Pattern

一、 門面(Facade)模式

外部與一個子系統的通訊必須通過一個統一的門面(Facade)物件進行,這就是門面模式。

醫院的例子

用一個例子進行說明,如果把醫院作為一個子系統,按照部門職能,這個系統可以劃分為掛號、門診、劃價、化驗、收費、取藥等。看病的病人要與這些部門打交道,就如同一個子系統的客戶端與一個子系統的各個類打交道一樣,不是一件容易的事情。

首先病人必須先掛號,然後門診。如果醫生要求化驗,病人必須首先劃價,然後繳款,才能到化驗部門做化驗。化驗後,再回到門診室。

解決這種不便的方法便是引進門面模式。可以設定一個接待員的位置,由接待員負責代為掛號、劃價、繳費、取藥等。這個接待員就是門面模式的體現,病人只接觸接待員,由接待員負責與醫院的各個部門打交道。

什麼是門面模式

門面模式要求一個子系統的外部與其內部的通訊必須通過一個統一的門面(Facade)物件進行。門面模式提供一個高層次的介面,使得子系統更易於使用。

就如同醫院的接待員一樣,門面模式的門面類將客戶端與子系統的內部複雜性分隔開,使得客戶端只需要與門面物件打交道,而不需要與子系統內部的很多物件打交道。


二、 門面模式的結構

門面模式是物件的結構模式。門面模式沒有一個一般化的類圖描述,下圖演示了一個門面模式的示意性物件圖:

 

在這個物件圖中,出現了兩個角色:

門面(Facade)角色:客戶端可以呼叫這個角色的方法。此角色知曉相關的(一個或者多個)子系統的功能和責任。在正常情況下,本角色會將所有從客戶端發來的請求委派到相應的子系統去。

子系統(subsystem)角色:可以同時有一個或者多個子系統。每一個子系統都不是一個單獨的類,而是一個類的集合。每一個子系統都可以被客戶端直接呼叫,或者被門面角色呼叫。子系統並不知道門面的存在,對於子系統而言,門面僅僅是另外一個客戶端而已。


三、 門面模式的實現

一個系統可以有幾個門面類

【GOF】的書中指出:在門面模式中,通常只需要一個門面類,並且此門面類只有一個例項,換言之它是一個單例類。當然這並不意味著在整個系統裡只能有一個門面類,而僅僅是說對每一個子系統只有一個門面類。或者說,如果一個系統有好幾個子系統的話,每一個子系統有一個門面類,整個系統可以有數個門面類。

為子系統增加新行為

初學者往往以為通過繼承一個門面類便可在子系統中加入新的行為,這是錯誤的。門面模式的用意是為子系統提供一個集中化和簡化的溝通管道,而不能向子系統加入新的行為。


四、 在什麼情況下使用門面模式

  • 為一個複雜子系統提供一個簡單介面
  • 提高子系統的獨立性
  • 在層次化結構中,可以使用Facade模式定義系統中每一層的入口。


五、 一個例子

我們考察一個保安系統的例子,以說明門面模式的功效。一個保安系統由兩個錄影機、三個電燈、一個遙感器和一個警報器組成。保安系統的操作人員需要經常將這些儀器啟動和關閉。

不使用門面模式的設計

首先,在不使用門面模式的情況下,操作這個保安系統的操作員必須直接操作所有的這些部件。下圖所示就是在不使用門面模式的情況下系統的設計圖。

 


可以看出,Client物件需要引用到所有的錄影機(Camera)、電燈(Light)、感應器(Sensor)和警報器(Alarm)物件。程式碼如下:

using System;

publicclass Camera
{
  
publicvoid TurnOn()
  
{
    Console.WriteLine(
"Turning on the camera.");
  }


  
publicvoid TurnOff()
  
{
    Console.WriteLine(
"Turning off the camera.");
  }


  
publicvoid Rotate(int degrees)
  
{
    Console.WriteLine(
"Rotating the camera by {0} degrees.", degrees);
  }

}


publicclass Light
{

  
publicvoid TurnOff()
  
{
    Console.WriteLine(
"Turning on the light.");
  }


  
publicvoid TurnOn()
  
{
    Console.WriteLine(
"Turning off the light.");
  }


  
publicvoid ChangeBulb()
  
{
    Console.WriteLine(
"changing the light-bulb.");
  }

}


publicclass Sensor
{
  
publicvoid Activate()
  
{
    Console.WriteLine(
"Activating the sensor.");
  }


  
publicvoid Deactivate()
  
{
    Console.WriteLine(
"Deactivating the sensor.");
  }


  
publicvoid Trigger()
  
{
    Console.WriteLine(
"The sensor has triggered.");
  }

}


publicclass Alarm
{

  
publicvoid Activate()
  
{
    Console.WriteLine(
"Activating the alarm.");
  }


  
publicvoid Deactivate()
  
{
    Console.WriteLine(
"Deactivating the alarm.");
  }


  
publicvoid Ring()
  
{
    Console.WriteLine(
"Ringing the alarm.");
  }


  
publicvoid StopRing()
  
{
    Console.WriteLine(
"Stop the alarm.");
  }

}


publicclass Client
{
  
privatestatic Camera camera1, camera2;
  
privatestatic Light light1, light2, light3;
  
privatestatic Sensor sensor;
  
privatestatic Alarm alarm;

  
static Client()
  
{
    camera1 
=new Camera();
    camera2 
=new Camera();
    light1 
=new Light();
    light2 
=new Light();
    light3 
=new Light();
    sensor 
=new Sensor();
    alarm 
=new Alarm();
  }
  

  
publicstaticvoid Main( string[] args )
  
{
    camera1.TurnOn();
    camera2.TurnOn();
    light1.TurnOn();
    light2.TurnOn();
    light3.TurnOn();
    sensor.Activate();
    alarm.Activate();
  }

}

六、 使用門面模式的設計

一個合情合理的改進方法就是準備一個系統的控制檯,作為保安系統的使用者介面。如下圖所示:

 

程式程式碼如下:

using System;

publicclass Camera
{
  
publicvoid TurnOn()
  
{
    Console.WriteLine(
"Turning on the camera.");
  }


  
publicvoid TurnOff()
  
{
    Console.WriteLine(
"Turning off the camera.");
  }


  
publicvoid Rotate(int degrees)
  
{
    Console.WriteLine(
"Rotating the camera by {0} degrees.", degrees);
  }

}


publicclass Light
{

  
publicvoid TurnOff()
  
{
    Console.WriteLine(
"Turning on the light.");
  }


  
publicvoid TurnOn()
  
{
    Console.WriteLine(
"Turning off the light.");
  }


  
publicvoid ChangeBulb()
  
{
    Console.WriteLine(
"changing the light-bulb.");
  }

}


publicclass Sensor
{
  
publicvoid Activate()
  
{
    Console.WriteLine(
"Activating the sensor.");
  }


  
publicvoid Deactivate()
  
{
    Console.WriteLine(
"Deactivating the sensor.");
  }


  
publicvoid Trigger()
  
{
    Console.WriteLine(
"The sensor has triggered.");
  }

}


publicclass Alarm

相關推薦

設計模式15Facade Pattern

一、 門面(Facade)模式 外部與一個子系統的通訊必須通過一個統一的門面(Facade)物件進行,這就是門面模式。 醫院的例子 用一個例子進行說明,如果把醫院作為一個子系統,按照部門職能,這個系統可以劃分為掛號、門診、劃價、化驗、收費、取藥等。看病的病人要與這些部門打交道,就如同一個子系統的客戶端與

C#設計模式4Simple Factory Pattern

工廠模式專門負責將大量有共同介面的類例項化。工廠模式可以動態決定將哪一個類例項化,不必事先知道每次要例項化哪一個類。工廠模式有以下幾種形態: 簡單工廠(Simple Factory)模式 工廠方法(Factory Method)模式 抽象工廠(Abstract Factory)模式 一、 

設計模式-15責任鏈模式 swift版

uiview ike recent ios part mage protoc ins handle 一,概念:   責任鏈模式(Chain of Responsibility Pattern)為請求創建了一個接收者對象的鏈。這種模式給予請求的類型,對請求的發送者和接收者進行

23種設計模式15:備忘錄模式

create getprop 是個 類型 創建 title pre 定義 當前 定義:在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象之外保存這個狀態。這樣就可以將該對象恢復到原先保存的狀態 類型:行為類模式。 類圖: 我們在編程的時候,經常需要保存對象的中

深入理解設計模式15:訪問者模式

一、什麼是訪問者模式 定義:表示一個作用於其物件結構中的各元素的操作,它使你可以在不改變各元素類的前提下定義作用於這些元素的新操作。 可以對定義這麼理解:有這麼一個操作,它是作用於一些元素之上的,而這些元素屬於某一個物件結構。同時這個操作是在不改變各元素類的前提下,在這個前提下定義新操作是訪問者模式精髓中

JAVA設計模式15:迭代器模式

迭代器模式是Java和.Net程式設計環境中非常常用的設計模式。此模式用於以順序方式訪問集合物件的元素,而不需要知道其底層表示。迭代器模式屬於行為模式類別。 實現例項 在這個例項中,將建立一個Iterator介面,它陳述了一個導航方法和一個Container介面,以及返回迭代器。 實現Con

設計模式Facade模式外觀模式

Facade模式(外觀模式) 為子系統中的一組介面提供一個統一的介面。Facade模式定義了一個更高層的介面,使系統更容易使用。 Facade模式 關鍵特徵 意圖 希望簡化 原系統的使用方

C++狀態模式詳解--設計模式15

State模式來源:   每個人、事物在不同的狀態下會有不同表現(動作),而一個狀態又會在不同的表現下轉移到下一個不同的狀態(State)。最簡單的一個生活中的例子就是:地鐵入口處,如果你放入正確的地鐵票,門就會開啟讓你通過。在出口處也是驗票,如果正確你就可以ok,否則就不讓

設計模式15--直譯器模式

直譯器模式(Interpreter Pattern)提供了評估語言的語法或表示式的方式,它屬於行為型模式。這種模式實現了一個表示式介面,該介面解釋一個特定的上下文。這種模式被用在 SQL 解析、符號處理引擎等。 介紹 意圖:給定一個語言,定義它的文法表示,並定義一個直譯器

《Head.First設計模式》的學習筆記15代理模式

 意圖: 為另一個物件提供一個替身或佔位符得以訪問這個物件。 結構: 接著我們來看RMI遠端代理: 1.我們先在伺服器註冊好幾個糖果機,由於我們現在使用RMI,我們需要構造糖果機和狀態。 糖果機首先變成一個服務,我們為糖果機建立一個遠端介面,讓開介面提供了一組可以遠端

pattern設計模式3 - Observer觀察者模式

獨立 使用 數據 技術 很多 調用 edi 基於 ace 源碼地址:https://github.com/vergilyn/design-patterns 另外一個大神很全的Github:https://github.com/iluwatar/java-design-pat

PHP設計模式——工廠模式(Factor Pattern)

@[TOC](PHP設計模式(二)——工廠模式(Factor Pattern)) 工廠模式(Factor Pattern),就是負責生成其他物件的類或方法 (一)為什麼需要工廠模式 工廠模式可以將物件的生產從直接new 一個物件,改成通過呼叫一個工廠方法生產

PHP設計模式——單例模式Singleton Pattern

PHP設計模式(一)——單例模式(Singleton Pattern) 單例模式(Singleton Pattern):顧名思義,就是隻有一個例項。作為物件的建立模式,單例模式確保某一個類只有一個例項,而且自行例項化並向整個系統提供這個例項。 (一)為

PHP設計模式——建造者模式(Builder Pattern)

@[TOC](PHP設計模式(三)——建造者模式(Builder Pattern)) 建造者模式(Builder Pattern):將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立不同的表示。 建造者模式是一步一步建立一個複雜的物件,它允許使用者只通過指定複雜物件的

設計模式6—— 結構型 ——外觀Facade

簡介 定義:又叫門面模式,提供一個統一的介面,用來訪問子系統中的一群介面。 解釋:外觀模式定義了一個高層介面,讓子系統更容易被使用。 型別:結構型 適用場景: 子系統越來越複雜,外觀模式能夠提供簡單的呼叫介面。

設計模式 Factory Pattern工廠模式

核心: 例項化物件,實現建立者和呼叫者的分離 簡單工廠模式 工廠方法模式 抽象工廠模式   面對物件設計的基本原則: ocp(open closed principle) 開閉原則:一個軟體的實體應當對拓展開放,對修改關閉 dip(dependence inversion princ

外觀模式 門面模式 Facade 創建型 設計模式十三

層次 好的 代碼 實例 width 負責 相互 one https 外觀模式(FACADE) 又稱為門面模式 意圖 為子系統中的一組接口提供一個一致的界面 Facade模式定義了一個高層接口,這一接口使得這一子系統更加易於使用。 意圖解析 隨著項目

設計模式Prototype Pattern 原型模式

通過new產生一個物件非常繁瑣,可以使用原型模式 原型模式實現: ——Cloneable介面和clone方法 ——Prototype模式實現起來最困難的地方是實現記憶體的複製和操作,Java中提供了clone方法省了大部分事情 案例:多利羊的克隆 package com.littlepage.

設計模式Builder Pattern建造者模式

在我們日常生活中,如構建一個飛船,一個手機,一棟建築,都會有非常複雜的組裝,這時候應該用到建造者模式 以建造一個飛船為例  案例:造小頁飛船 1.飛船各部分元件 package com.littlepage.BuilderPattern; public interface AirSh

外觀模式 門面模式 Facade 建立型 設計模式十三

外觀模式(FACADE) 又稱為門面模式   原文地址:外觀模式 門面模式 Facade 建立型 設計模式(十三) 意圖 為子系統中的一組介面提供一個一致的介面 Facade模式定義了一個高層介面,這一介面使得這一子系統更加易於使用。 意圖解析 隨著專