java 開發模式之八 : 外觀模式(門面模式)

原理或定義

它隱藏系統的複雜性,並向客戶端提供一個可以訪問系統的接口。這種類型的設計模式屬於結構型模式,它向現有的系統添加一個接口,來隱藏系統的複雜性,爲子系統中的一組接口提供了一個統一的高層訪問接口,這個接口使得子系統更容易被訪問或使用。這種模式涉及到一個單一的類,該類提供了客戶端請求的簡化方法和對現有系統類方法的委託調用。

結構

門面角色( facade ):這是門面模式的核心。它被客戶角色調用,因此它熟悉子系統的功能。它內部根據客戶角色已有的需求預定了幾種功能組合;
子系統角色(subsystem實現了子系統的功能。對它而言, façade角色就和客戶角色一樣是未知的,它沒有任何 façade角色的信息和鏈接;
客戶角色調用 façade角色來完成要得到的功能;

類圖


案例與代碼

本模式以智能家電控制項目爲示例

使用遙控器通過中央控制器控制DVD和音響



設備類:

public class DVDPlayer {
	private static DVDPlayer instance = null;

	private DVDPlayer() {

	}

	public static DVDPlayer getInstance() {
		if (instance == null) {
			instance = new DVDPlayer();
		}

		return instance;
	}
	
	public void on() {
		System.out.println("DVDPlayer On");
	}

	public void off() {
		System.out.println("DVDPlayer Off");
	}

	public void play() {
		System.out.println("DVDPlayer is playing");
	}
	
	public void pause() {
		System.out.println("DVDPlayer  pause");
	}
	
	public void setdvd() {
		System.out.println("DVDPlayer  is setting dvd");
	}
}
public class Stereo {


	private static Stereo instance = null;
	private int volume = 5;


	private Stereo() {


	}


	public static Stereo getInstance() {
		if (instance == null) {
			instance = new Stereo();
		}


		return instance;
	}


	public void on() {
		System.out.println("Stereo On");
	}


	public void off() {
		System.out.println("Stereo Off");
	}


	public void setVolume(int vol) {


		volume = vol;
		System.out.println("the volume of Stereo is set to  " + volume);
	}


	public void addVolume() {
		if (volume < 11) {
			volume++;
			setVolume(volume);
		}


	}


	public void subVolume() {
		if (volume > 0) {
			volume--;
			setVolume(volume);
		}


	}


}


中央控制器類/外觀類:

public class TheaterFacade {
	private Stereo mStereo;
	private DVDPlayer mDVDPlayer;

	public TheaterFacade() {
		mStereo = Stereo.getInstance();
		mDVDPlayer = DVDPlayer.getInstance();
	}

	public void dvd_on(){
		mDVDPlayer.on();
	}

	public void setdvd(){
		mDVDPlayer.setdvd();
	}

	public void dvd_off(){
		mDVDPlayer.off();
	}

	public void play() {
		mDVDPlayer.play();
	}

	public void pause() {
		mDVDPlayer.pause();
	}

	public void stereo_off(){
		mStereo.on();
	}

	public void stereo_on(){
		mStereo.off();
	}

	public void addVolume() {
		mStereo.addVolume();
	}

	public void subVolume() {
		mStereo.subVolume();
	}
}

Client / 遙控器類:

public class Control {
	private TheaterFacade facade;

	public Control() {
		facade = new TheaterFacade();
	}

	public void button1(){
		facade.dvd_on();
	}

	public void button2(){
		facade.setdvd();
	}

	public void button3(){
		facade.dvd_off();
	}

	public void button4() {
		facade.play();
	}

	public void button5() {
		facade.pause();
	}

	public void button6(){
		facade.stereo_off();
	}

	public void button7(){
		facade.stereo_on();
	}

	public void button8() {
		facade.addVolume();
	}

	public void button9() {
		facade.subVolume();
	}
}

提供一個統一的接口,來訪問子系統中一羣功能相關接口

最少知識原則:儘量減少對象之間的交互,只留幾個“密友”

對象的方法調用範圍:
該對象本身
作爲參數傳進來的對象
此方法創建和實例化的對象
對象的組件


使用場景

1. 爲一個複雜子系統提供一個簡單接口。

2.提高子系統的獨立性。

3.在層次化結構中,可以使用Facade模式定義系統中每一層的入口

 

優缺點

主要優點有:

1.對客戶程序隱藏子系統細節,因而減少了客戶對於子系統的耦合,能夠擁抱變化;

2.外觀類對子系統的接口封裝,使得系統更易於使用;

3.更好的劃分訪問層次。把需要暴露給外部的功能集中到外觀類中,這樣既方便客戶端使用,也很好地隱藏了內部的細節。

 

缺點主要有

1.外觀類接口膨脹,由於子系統的接口都由外觀類統一對外暴露,使得外觀類的 API 接口較多,在一定程度上增加了用戶使用成本;

2.外觀類沒有遵循開閉原則,當業務出現變更時,可能需要直接修改外觀類。

發佈了39 篇原創文章 · 獲贊 0 · 訪問量 5125
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章