設計模式之外觀模式(Facade Pattern)

當一個系統的功能越來越強,子系統會越來越多,客戶對系統的訪問也變得越來越複雜。這時如果系統內部發生改變,客戶端也要跟着改變,這違背了“開閉原則”,也違背了“迪米特法則”,所以有必要爲多個子系統提供 一個統一的接口 ,從而降低系統的耦合度,這就是外觀模式的目標。

客戶去房產局辦理房產證過戶要遇到的部門和窗口:

辦理房產證過戶的相關部門

一、外觀模式的定義與特點

定義:

外觀模式,是一種通過爲多個複雜的子系統提供 一個一致的接口 ,而使這些子系統更加容易被訪問的模式。該模式對外有一個統一接口,外部應用程序不用關心內部子系統的具體的細節,這樣會大大降低應用程序的複雜度,提高了程序的可維護性。

優點:

  1. 降低了子系統與客戶端之間的耦合度,使得子系統的變化不會影響調用它的客戶類。
  2. 對客戶屏蔽了子系統組件,減少了客戶處理的對象數目,並使得子系統使用起來更加容易。
  3. 降低了大型軟件系統中的編譯依賴性,簡化了系統在不同平臺之間的移植過程,因爲編譯一個子系統不會影響其他的子系統,也不會影響外觀對象。

缺點:

  1. 不能很好地限制客戶使用子系統類。
  2. 增加新的子系統可能需要修改外觀類或客戶端的源代碼,違背了“開閉原則”。

二、UML類圖

外觀模式的結構比較簡單,主要是定義了一個高層接口。它包含了對各個子系統的引用,客戶端可以通過它訪問各個子系統的功能。現在來分析其基本結構和實現方法。

外觀模式包含以下主要角色:

  1. Facade(外觀):爲多個 SubSystem 對外提供一個共同的接口。
  2. SubSystem(子系統):實現系統的部分功能,客戶可以通過外觀角色訪問它。
  3. Client(客戶):通過一個 Facade 角色訪問各個子系統的功能。

在這裏插入圖片描述

三、代碼

SubSystem:DVDPlayer

public class DVDPlayer {
	
	//使用單例模式, 使用餓漢式
	private static DVDPlayer instance = new DVDPlayer();
	
	public static DVDPlayer getInstanc() {
		return instance;
	}
	
	public void on() {
		System.out.println(" dvd on ");
	}
	public void off() {
		System.out.println(" dvd off ");
	}
	
	public void play() {
		System.out.println(" dvd is playing ");
	}
	
	//....
	public void pause() {
		System.out.println(" dvd pause ..");
	}
}

SubSystem:Projector(放映機)

/**
 * 放映機
 */
public class Projector {

	private static Projector instance = new Projector();

	public static Projector getInstance() {
		return instance;
	}

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

	public void off() {
		System.out.println(" Projector ff ");
	}

	public void focus() {
		System.out.println(" Projector is Projector  ");
	}
}

SubSystem:Screen(屏幕)

/**
 * 屏幕
 */
public class Screen {

	private static Screen instance = new Screen();
	
	public static Screen getInstance() {
		return instance;
	}
	
	/**
	 *  屏幕收起
	 */
	public void up() {
		System.out.println(" Screen up ");
	}
	
	
	/**
	 *  屏幕放下
	 */
	public void down() {
		System.out.println(" Screen down ");
	}
}

SubSystem:Stereo(立體聲音響)

/**
 * 立體聲音響
 */
public class Stereo {

	private static Stereo instance = new Stereo();
	
	public static Stereo getInstance() {
		return instance;
	}
	
	public void on() {
		System.out.println(" Stereo on ");
	}
	
	public void off() {
		System.out.println(" Screen off ");
	}
	
	public void up() {
		System.out.println(" Screen up.. ");
	}
}

SubSystem:TheaterLight(劇場燈光)

/**
 * 劇場燈光
 */
public class TheaterLight {

	private static TheaterLight instance = new TheaterLight();

	public static TheaterLight getInstance() {
		return instance;
	}

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

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

	/**
	 * 調暗
	 */
	public void dim() {
		System.out.println(" TheaterLight dim.. ");
	}

	/**
	 * 調亮
	 */
	public void bright() {
		System.out.println(" TheaterLight bright.. ");
	}
}

Facade :HomeTheaterFacade(家庭影院項目)

/**
 * 家庭影院項目
 */
public class HomeTheaterFacade {
	
	//定義各個子系統對象
	
	/** 劇場燈光 */
	private TheaterLight theaterLight;
	/** 立體聲音響 */
	private Stereo stereo;
	/** 放映機 */
	private Projector projector;
	/**  屏幕  */
	private Screen screen;
	private DVDPlayer dVDPlayer;
	
	
	//構造器
	public HomeTheaterFacade() {
		super();
		this.theaterLight = TheaterLight.getInstance();
		this.stereo = Stereo.getInstance();
		this.projector = Projector.getInstance();
		this.screen = Screen.getInstance();
		this.dVDPlayer = DVDPlayer.getInstanc();
	}

	//操作分成 4 步
	/**
	 * 準備
	 */
	public void ready() {
		screen.down();
		projector.on();
		stereo.on();
		dVDPlayer.on();
		theaterLight.dim();
	}
	
	/**
	 * 播入
	 */
	public void play() {
		dVDPlayer.play();
	}
	
	/**
	 * 暫停
	 */
	public void pause() {
		dVDPlayer.pause();
	}
	
	/**
	 * 結束
	 */
	public void end() {
		theaterLight.bright();
		screen.up();
		projector.off();
		stereo.off();
		dVDPlayer.off();
	}	
}

Client

public class Client {

	public static void main(String[] args) {
		//這裏直接調用。。 很麻煩
		HomeTheaterFacade homeTheaterFacade = new HomeTheaterFacade();
		
		//準備
		homeTheaterFacade.ready();
		//播放
		homeTheaterFacade.play();
		
		//結束
		homeTheaterFacade.end();
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章