2011-03-09 96 views
145

門面一個包含很多其他類的類?什麼是門面設計模式?

是什麼使它成爲設計模式?對我而言,它就像一個普通的班級。

你能解釋一下嗎門面圖案?

+4

每個設計模式都在其實現一堆類。 – 2011-03-09 07:08:56

+1

爲什麼我得到-1票?不是一個合適的問題或一個簡單的問題? – kevin 2011-03-09 07:09:21

+6

@axarydax - 由於我是新設計模式,我不知道如何提出一個難題。稍後再試! – kevin 2011-03-09 07:48:38

回答

146

設計模式是解決循環問題的常用方法。所有設計模式中的類都只是普通的類。重要的是它們是如何構建的以及它們如何一起工作以最好的方式解決給定的問題。

外觀設計模式簡化了與複雜系統的接口;因爲它通常由組成複雜系統子系統的所有類組成。

Facade將用戶從系統的複雜細節中屏蔽出來,併爲它們提供simplified view,它是easy to use。它也是decouples從子系統的細節中使用系統的代碼,使得以後更容易修改系統。

http://www.dofactory.com/Patterns/PatternFacade.aspx

http://www.blackwasp.co.uk/Facade.aspx

此外,什麼是一邊學習設計模式重要的是要能夠識別哪種模式適合您的特定問題,然後適當地使用它。濫用模式或者僅僅因爲知道它而試圖使它適應某些問題是非常普遍的事情。在學習\使用設計模式時要注意這些缺陷。

+3

@unmesh - 是的,我仍然不知道何時使用這些設計模式。 – kevin 2011-03-09 07:34:02

+0

@kevin - 你唯一的辦法就是多讀些關於他們的經驗,並與他們建立經驗:) – 2011-03-09 07:36:34

+7

@kevin:知道何時使用它們是最困難的部分。理論上,模式可能很容易,但在實踐中它們很難。你只能學習這種經驗,即。編碼,編碼,編碼。 – 2011-03-09 23:51:17

6

正面圖案是結果中許多其他接口的包裝,以產生更簡單的接口。

設計模式很有用,因爲它們可以解決重複發生的問題,並且通常可以簡化代碼。在一組同意使用相同模式的開發人員團隊中,在維護其他代碼時可以提高效率和理解。

嘗試閱讀關於多個模式:

外觀模式:http://www.dofactory.com/Patterns/PatternFacade.aspx#_self1

或者更一般地:http://www.dofactory.com/Patterns/Patterns.aspx

+0

http://www.nileshgule.com/2012/07/facade-design-pattern.html我試圖用一個住房貸款驗證過程的例子來描述Facade設計模式。 – 2012-07-16 14:36:11

10

甲門面不應該被描述爲含有大量的其它類的一個類。它實際上是這個類的一個接口,並且應該使類的使用更容易,否則facade類是無用的。

31

正如前面的答案中所解釋的,它爲消費客戶提供了一個簡單的界面。 例如:「觀看ESPN」是預期的功能。但它涉及以下幾個步驟:

  1. 如果需要,打開電視;
  2. 檢查衛星/有線功能;
  3. 如果需要切換到ESPN。

但外觀將簡化這一點,只是向客戶提供「觀看ESPN」功能。

4

Facade是一個具有位於工具包和完整應用程序之間的功能級別的類,它提供了包或子系統中類的簡化使用。 Facade模式的意圖是提供一個使子系統易於使用的界面。 - 摘自book C#中的設計模式。

5

正面圖案的另外一個用途可能是減少團隊的學習曲線。讓我舉一個例子:

讓我們假設你的應用程序需要通過使用Excel提供的COM對象模型與MS Excel進行交互。你的一個團隊成員知道所有的Excel API,並在其上創建一個Facade,它滿足應用程序的所有基本場景。團隊中的其他成員不需要花時間學習Excel API。團隊可以使用外觀,而無需瞭解實現方案所涉及的內部組件或所有MS Excel對象。這不是很好嗎?

因此,它提供了一個複雜的子系統之上的簡化和統一的接口。

3

正面的另一個示例: 表示您的應用程序連接到數據庫並在UI上顯示結果。您可以使用Facade使應用程序可配置,如使用數據庫運行或使用模擬對象。因此,您將對Facade類進行所有數據庫調用,並在其中讀取應用程序配置並決定觸發數據庫查詢或返回模擬對象。這種方式應用程序成爲db獨立的情況下數據庫不可用。

6

一個外觀暴露了大多數被調用的簡化函數,並且實現隱藏了客戶必須處理的複雜性。一般來說,實現使用多個包,類和函數。寫得很好的外觀使其他類很少直接訪問。例如,當我訪問ATM並退出一些金額時。 ATM隱藏它是直接進入所擁有的銀行,還是通過協商的外部銀行網絡進行。自動櫃員機的功能就像一個門面,消耗了多個設備和子系統,作爲客戶我不必直接處理。

67

Wikipedia有一個很好的門面模式的例子。

/* Complex parts */ 

class CPU { 
    public void freeze() { ... } 
    public void jump(long position) { ... } 
    public void execute() { ... } 
} 

class Memory { 
    public void load(long position, byte[] data) { ... } 
} 

class HardDrive { 
    public byte[] read(long lba, int size) { ... } 
} 

/* Facade */ 

class ComputerFacade { 
    private CPU processor; 
    private Memory ram; 
    private HardDrive hd; 

    public ComputerFacade() { 
     this.processor = new CPU(); 
     this.ram = new Memory(); 
     this.hd = new HardDrive(); 
    } 

    public void start() { 
     processor.freeze(); 
     ram.load(BOOT_ADDRESS, hd.read(BOOT_SECTOR, SECTOR_SIZE)); 
     processor.jump(BOOT_ADDRESS); 
     processor.execute(); 
    } 
} 

/* Client */ 

class You { 
    public static void main(String[] args) { 
     ComputerFacade computer = new ComputerFacade(); 
     computer.start(); 
    } 
} 
+4

這是一個很好的例子。如果客戶選擇了,則客戶需要能夠將門面中的所有步驟拼湊在一起,私人方法不應隱藏任何內容。 – Rob 2014-11-20 23:29:35

+1

Imho這不是一個好例子,因爲它沒有強調用例。正如TO所說,這個例子只是一個普通的課程。與硬件的關聯是一個組合。也許矯枉過正維基上的例子,但使用依賴注入而不是實例化子模塊會強調意圖並可能避免TO的困惑。 – ManuelSchneid3r 2016-10-05 21:29:56

27

門面隱藏了系統的複雜性,並提供從其中客戶機可以訪問系統到客戶端的接口。

public class Inventory { 
public String checkInventory(String OrderId) { 
    return "Inventory checked"; 
} 
} 

public class Payment { 
public String deductPayment(String orderID) { 
    return "Payment deducted successfully"; 
} 
} 


public class OrderFacade { 
private Payment pymt = new Payment(); 
private Inventory inventry = new Inventory(); 

public void placeOrder(String orderId) { 
    String step1 = inventry.checkInventory(orderId); 
    String step2 = pymt.deductPayment(orderId); 
    System.out 
      .println("Following steps completed:" + step1 
        + " & " + step2); 
    } 
} 

public class Client { 
     public static void main(String args[]){ 
     OrderFacade orderFacade = new OrderFacade(); 
     orderFacade.placeOrder("OR123456"); 
     System.out.println("Order processing completed"); 
     } 
    } 
+0

是否允許子系統在不通過'OrderFacade'的情況下彼此通信?在你的例子中,在「付款」和「庫存」之間? – Isuru 2016-02-08 06:43:23

1

它基本上是單窗口清除系統。

3

設計模式是軟件設計中給定上下文中常見問題的通用可重用解決方案。

Facade設計模式是一種結構模式,因爲它定義了在類或實體之間創建關係的方式。門面設計模式用於定義到更復雜子系統的簡化界面。

當使用大量相互依賴的類或需要使用多種方法的類時,尤其是使用起來複雜或難以理解的類時,外觀模式非常理想。 Facade類是一個「包裝器」,它包含一組容易理解且易於使用的成員。這些成員代表Facade用戶訪問子系統,隱藏實現細節。

當包裝設計不佳的子系統時,外觀設計模式特別有用,但由於源代碼不可用或現有接口被廣泛使用而無法重構。有時您可能決定實施多個門面以提供用於不同目的的功能子集。

門面模式的一個示例用途是將網站與業務應用程序集成。現有軟件可能包含大量必須以特定方式訪問的業務邏輯。該網站可能只需要有限的訪問此業務邏輯。例如,網站可能需要顯示出售物品是否達到了有限的庫存水平。 Facade類的IsLowStock方法可以返回一個布爾值來指示這一點。在幕後,這種方法可能會隱藏處理當前實物庫存,傳入庫存,分配物料和每個物料的低庫存水平的複雜性。

2

關於你查詢的最好的解釋:

是門面裏面包含了很多其他類的一類?

是的。它是應用程序中許多子系統的包裝器。

是什麼讓它成爲設計模式?對我來說,它就像一個普通的類

所有的設計模式也是正常的類。 @Unmesh Kondolikar正確回答了這個問題。

你能解釋一下這個門面,我是新設計模式。

根據GoF的,門面設計模式是如defind:

提供一個統一的接口子系統中的一組接口。外觀模式定義了一個更高層次的接口,使子系統更容易使用

Facade模式通常適用於:需要

  1. 一個簡單的接口來訪問一個複雜的系統。
  2. 子系統的抽象和實現緊密耦合。
  3. 需要一個分層軟件的每個級別的入口點。
  4. 系統非常複雜或難以理解。

讓我們以cleartrip網站爲例說一個真實的例子。

本網站提供的選項預訂

  1. 機票
  2. 酒店
  3. 機票+酒店

代碼片段:

import java.util.*; 

public class TravelFacade{ 
    FlightBooking flightBooking; 
    TrainBooking trainBooking; 
    HotelBooking hotelBooking; 

    enum BookingType { 
     Flight,Train,Hotel,Flight_And_Hotel,Train_And_Hotel; 
    }; 

    public TravelFacade(){ 
     flightBooking = new FlightBooking(); 
     trainBooking = new TrainBooking(); 
     hotelBooking = new HotelBooking();   
    } 
    public void book(BookingType type, BookingInfo info){ 
     switch(type){ 
      case Flight: 
       // book flight; 
       flightBooking.bookFlight(info); 
       return; 
      case Hotel: 
       // book hotel; 
       hotelBooking.bookHotel(info); 
       return; 
      case Train: 
       // book Train; 
       trainBooking.bookTrain(info); 
       return; 
      case Flight_And_Hotel: 
       // book Flight and Hotel 
       flightBooking.bookFlight(info); 
       hotelBooking.bookHotel(info); 
       return; 
      case Train_And_Hotel: 
       // book Train and Hotel 
       trainBooking.bookTrain(info); 
       hotelBooking.bookHotel(info); 
       return;     
     } 
    } 
} 
class BookingInfo{ 
    String source; 
    String destination; 
    Date fromDate; 
    Date  toDate; 
    List<PersonInfo> list; 
} 
class PersonInfo{ 
    String name; 
    int  age; 
    Address address; 
} 
class Address{ 

} 
class FlightBooking{ 
    public FlightBooking(){ 

    } 
    public void bookFlight(BookingInfo info){ 

    } 
} 
class HotelBooking{ 
    public HotelBooking(){ 

    } 
    public void bookHotel(BookingInfo info){ 

    } 
} 
class TrainBooking{ 
    public TrainBooking(){ 

    } 
    public void bookTrain(BookingInfo info){ 

    } 
} 

說明:

  1. FlightBooking, TrainBooking and HotelBooking大系統的不同子系統:TravelFacade

  2. TravelFacade提供了一個簡單的界面,預定以下選項之一

    Flight Booking 
    Train Booking 
    Hotel Booking 
    Flight + Hotel booking 
    Train + Hotel booking 
    
  3. 書TravelFacade的API內部調用子系統的以下API

    flightBooking.bookFlight 
    trainBooking.bookTrain(info); 
    hotelBooking.bookHotel(info); 
    
  4. 通過這種方式,TravelFacade提供了更簡單,更簡單的API,無需公開子系統API。

關鍵要點:(從journaldev文章的Pankaj庫馬爾

  1. 外觀模式更像是輔助客戶端應用程序
  2. 外觀模式可以在任何適用開發點通常爲當接口數量增長並且系統完成時 x
  3. 子系統接口不知道正面和它們不應該有門面接口的任何參考
  4. 外觀模式應適用於類似種接口,其目的是提供一種單個接口而不是多個接口,可以執行類似的作業

看看sourcemaking文章,以便更好地理解。

3

Facade討論在單個接口對象中封裝複雜子系統。這減少了成功利用子系統所需的學習曲線。它還促進了子系統與潛在的許多客戶的解耦。另一方面,如果Facade是子系統的唯一訪問點,則會限制「強大用戶」可能需要的功能和靈活性。

1

門面模式爲子系統接口組提供統一接口。 Facade定義了一個高級界面,它簡化了子系統的工作。