1. 程式人生 > >設計模式之外觀(facade)模式

設計模式之外觀(facade)模式

一、概念介紹

  外觀模式(Facade),他隱藏了系統的複雜性,並向客戶端提供了一個可以訪問系統的介面。這種型別的設計模式屬於結構性模式。為子系統中的一組介面提供了一個統一的訪問介面,這個介面使得子系統更容易被訪問或者使用。 

二、角色及使用場景

  簡單來說,該模式就是把一些複雜的流程封裝成一個介面供給外部使用者更簡單的使用。這個模式中,設計到3個角色。

  1).門面角色:外觀模式的核心。它被客戶角色呼叫,它熟悉子系統的功能。內部根據客戶角色的需求預定了幾種功能的組合。

  2).子系統角色:實現了子系統的功能。它對客戶角色和Facade時未知的。它內部可以有系統內的相互互動,也可以由供外界呼叫的介面。

  3).客戶角色:通過呼叫Facede來完成要實現的功能。

  使用場景:

  1- 為複雜的模組或子系統提供外界訪問的模組;

  2- 子系統相互獨立;

  3- 在層析結構中,可以使用外觀模式定義系統的每一層的入口。

三、例項

  下面,我們就通過一個簡單的例子來實現該模式。

  每個Computer都有CPU、Memory、Disk。在Computer開啟和關閉的時候,相應的部件也會開啟和關閉,所以,使用了該外觀模式後,會使使用者和部件之間解耦。如:

包體的建立:

程式碼實現

首先是子系統類:

 【程式碼清單--1】

複製程式碼

 1 package com.huawei.facadeDesign.children;
 2 
 3 import org.apache.log4j.Logger;
 4 
 5 /**
 6  * cpu子系統類
 7  * @author Administrator
 8  *
 9  */
10 public class CPU 
11 {
12     public static final Logger LOGGER = Logger.getLogger(CPU.class);
13     public void start()
14     {
15         LOGGER.info("cpu is start...");
16     }
17     
18     public void shutDown()
19     {
20         LOGGER.info("CPU is shutDown...");
21     }
22 }

複製程式碼

 【程式碼清單--2】

複製程式碼

 1 package com.huawei.facadeDesign.children;
 2 
 3 import org.apache.log4j.Logger;
 4 
 5 /**
 6  * Disk子系統類
 7  * @author Administrator
 8  *
 9  */
10 public class Disk
11 {
12     public static final Logger LOGGER = Logger.getLogger(Disk.class);
13     public void start()
14     {
15         LOGGER.info("Disk is start...");
16     }
17     
18     public void shutDown()
19     {
20         LOGGER.info("Disk is shutDown...");
21     }
22 }

複製程式碼

【程式碼清單--3】

複製程式碼

 1 package com.huawei.facadeDesign.children;
 2 
 3 import org.apache.log4j.Logger;
 4 
 5 /**
 6  * Memory子系統類
 7  * @author Administrator
 8  *
 9  */
10 public class Memory
11 {
12     public static final Logger LOGGER = Logger.getLogger(Memory.class);
13     public void start()
14     {
15         LOGGER.info("Memory is start...");
16     }
17     
18     public void shutDown()
19     {
20         LOGGER.info("Memory is shutDown...");
21     }
22 }

複製程式碼

然後是,門面類Facade

【程式碼清單--4】

複製程式碼

 1 package com.huawei.facadeDesign.facade;
 2 
 3 import org.apache.log4j.Logger;
 4 
 5 import com.huawei.facadeDesign.children.CPU;
 6 import com.huawei.facadeDesign.children.Disk;
 7 import com.huawei.facadeDesign.children.Memory;
 8 
 9 
10 /**
11  * 門面類(核心)
12  * @author Administrator
13  *
14  */
15 public class Computer
16 {
17     public static final Logger LOGGER = Logger.getLogger(Computer.class);
18     
19     private CPU cpu;
20     private Memory memory;
21     private Disk disk;
22     public Computer()
23     {
24         cpu = new CPU();
25         memory = new Memory();
26         disk = new Disk();
27     }
28     public void start()
29     {
30         LOGGER.info("Computer start begin");
31         cpu.start();
32         disk.start();
33         memory.start();
34         LOGGER.info("Computer start end");
35     }
36     
37     public void shutDown()
38     {
39         LOGGER.info("Computer shutDown begin");
40         cpu.shutDown();
41         disk.shutDown();
42         memory.shutDown();
43         LOGGER.info("Computer shutDown end...");
44     }
45 }

複製程式碼

最後為,客戶角色。

【程式碼清單--5】

複製程式碼

 1 package com.huawei.facadeDesign;
 2 
 3 import org.apache.log4j.Logger;
 4 
 5 import com.huawei.facadeDesign.facade.Computer;
 6 
 7 /**
 8  * 客戶端類
 9  * @author Administrator
10  *
11  */
12 public class Cilent {
13     public static final Logger LOGGER = Logger.getLogger(Cilent.class);
14     public static void main(String[] args) 
15     {
16         Computer computer = new Computer();
17         computer.start();
18         LOGGER.info("=================");
19         computer.shutDown();
20     }
21 
22 }

複製程式碼

 【程式碼清單--6】執行結果

  從上面的例項來看,有了這個Facade類,也就是Computer類,使用者就不用親自去呼叫子系統中的Disk,Memory、CPU類了,不需要知道系統內部的實現細節,甚至都不用知道系統內部的構成。客戶端只需要跟Facade互動就可以了。

四、優點

  - 鬆散耦合

  使得客戶端和子系統之間解耦,讓子系統內部的模組功能更容易擴充套件和維護;

  - 簡單易用

  客戶端根本不需要知道子系統內部的實現,或者根本不需要知道子系統內部的構成,它只需要跟Facade類互動即可。

  - 更好的劃分訪問層次

  有些方法是對系統外的,有些方法是系統內部相互互動的使用的。子系統把那些暴露給外部的功能集中到門面中,這樣就可以實現客戶端的使用,很好的隱藏了子系統內部的細節。

接下來是我自己的理解

其實facade模式就是封裝(只不過程式碼中大多是相互呼叫,邏輯比較少)。

首先,有幾個子系統類,每個子系統類實現不同的功能。。

然後,寫一個外觀類,把不同子系統的功能的不同組合分別封裝為外觀類的不同方法。

最後,此時客戶呼叫外觀類的某個方法,就相當於直接呼叫該方法所包含的幾個不同的子系統功能。(如果不用外觀模式,那客戶也可以自己呼叫對應的那幾個子系統功能,只不過用了外觀模式之後,客戶呼叫那些功能就更加簡單了,隱藏了呼叫子系統的細節)