1. 程式人生 > >Java設計模式(九)之結構型模式:外觀模式

Java設計模式(九)之結構型模式:外觀模式

一、定義:

所謂外觀模式,就是提供一個統一的介面,用來訪問子系統中的一群介面。

外觀模式定義了一個高層介面,讓子系統更容易使用。如下圖,是使用外觀模式後將子系統的使用變得更加簡單。

在引入外觀模式後,客戶只需要與外觀角色打交道,客戶與子系統的複雜關係由外觀角色來實現,從而降低了系統的耦合度。

如果我們沒有Facade類,那麼,Subsystem 他們之間將會相互持有例項,產生關係,這樣會造成嚴重的依賴,修改一個類,可能會帶來其他類的修改,這不是我們想要看到的,有了Facade類,他們之間的關係被放在了Facade類裡,這樣就起到了解耦的作用,這,就是外觀模式!

二、模式結構:

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

子系統(SubSystem)角色 :可以同時有一個或者多個子系統。每個子系統都不是一個單獨的類,而是一個類的集合(如上面的子系統就是由SubSystemA、SubSystemB、SubSystemC、SubSystemD 幾個類組合而成)。每個子系統都可以被客戶端直接呼叫,或者被門面角色呼叫。子系統並不知道門面的存在,對於子系統而言,門面僅僅是另外一個客戶端而已。

三、模式的實現:

我們以一個計算機的啟動過程為例:

我們先看下實現類:

public class CPU {
	
	public void startup(){
		System.out.println("cpu startup!");
	}
	
	public void shutdown(){
		System.out.println("cpu shutdown!");
	}
}
public class Memory {
	
	public void startup(){
		System.out.println("memory startup!");
	}
	
	public void shutdown(){
		System.out.println("memory shutdown!");
	}
}
public class Disk {
	
	public void startup(){
		System.out.println("disk startup!");
	}
	
	public void shutdown(){
		System.out.println("disk shutdown!");
	}
}
//Facade類
public class Computer {
	private CPU cpu;
	private Memory memory;
	private Disk disk;
	
	public Computer(){
		cpu = new CPU();
		memory = new Memory();
		disk = new Disk();
	}
	
	public void startup(){
		System.out.println("start the computer!");
		cpu.startup();
		memory.startup();
		disk.startup();
		System.out.println("start computer finished!");
	}
	
	public void shutdown(){
		System.out.println("begin to close the computer!");
		cpu.shutdown();
		memory.shutdown();
		disk.shutdown();
		System.out.println("computer closed!");
	}
}

 User類如下:

public class User {
 
	public static void main(String[] args) {
		Computer computer = new Computer();
		computer.startup();
		computer.shutdown();
	}
}

執行結果:

start the computer!
cpu startup!
memory startup!
disk startup!
start computer finished!
begin to close the computer!
cpu shutdown!
memory shutdown!
disk shutdown!
computer closed!

Facade類其實相當於CPU、Disk、Memory模組的外觀介面,有了這個Facade類,那麼客戶端就不需要親自呼叫子系統中的CPU、Disk、Memory模組了,也不需要知道系統內部的實現細節,甚至都不需要知道CPU、Disk、Memory模組的存在,客戶端只需要跟Facade類互動就好了,從而更好地實現了客戶端和子系統中CPU、Disk、Memory模組的解耦,讓客戶端更容易地使用系統。

四、外觀模式小結:

1、一個系統可以有幾個外觀類:

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

2、為子系統增加新行為:

初學者往往以為通過繼承一個外觀類便可在子系統中加入新的行為,這是錯誤的。外觀模式的用意是為子系統提供一個集中化和簡化的溝通管道,而不能向子系統加入新的行為。比如醫院中的接待員並不是醫護人員,接待員並不能為病人提供醫療服務。

3、外觀模式的優點:

(1)鬆散耦合:外觀模式鬆散了客戶端與子系統的耦合關係,讓子系統內部的模組能更容易擴充套件和維護。

(2)簡單易用:外觀模式讓子系統更加易用,客戶端不再需要了解子系統內部的實現,也不需要跟眾多子系統內部的模組進行互動,只需要跟外觀類互動就可以了。

(3)更好的劃分訪問層次:通過合理使用Facade,可以幫助我們更好地劃分訪問的層次。有些方法是對系統外的,有些方法是系統內部使用的。把需要暴露給外部的功能集中到門面中,這樣既方便客戶端使用,也很好地隱藏了內部的細節。

4、外觀模式的缺點:

(1)不能很好地限制客戶使用子系統類,如果對客戶訪問子系統類做太多的限制則減少了可變性和靈活性。

(2)在不引入抽象外觀類的情況下,增加新的子系統可能需要修改外觀類或客戶端的原始碼,違背了“開閉原則”。

5、適用場景:

(1)當要為一個複雜子系統提供一個簡單介面時可以使用外觀模式。

(2)客戶程式與多個子系統之間存在很大的依賴性。引入外觀類將子系統與客戶以及其他子系統解耦,可以提高子系統的獨立性和可移植性。

參考部落格連結: