設計模式——外觀模式

9.

OO原則:最少知識原則——只和你的密友談話

(即只調用屬於以下範圍的方法:

①該對象本身

②被當作方法的參數而傳遞進來的對象

③此方法索創建或實例化的任何對象

④對象的任何組件)

OO模式:外觀模式——提供一個統一的接口,用來訪問子系統中的一羣接口。外觀定義了一個高層接口,讓子系統更容易使用。


例子:觀看家庭影院的準備和看完後關閉設備等工作。


public class HomeTheaterFacade {
	Amplifier amp;
	Tuner tuner;
	DvdPlayer dvd;
	CdPlayer cd;
	Projector projector;
	TheaterLights lights;
	Screen screen;
	PopcornPopper popper;
 
	public HomeTheaterFacade(Amplifier amp, 
				 Tuner tuner, 
				 DvdPlayer dvd, 
				 CdPlayer cd, 
				 Projector projector, 
				 Screen screen,
				 TheaterLights lights,
				 PopcornPopper popper) {
 
		this.amp = amp;
		this.tuner = tuner;
		this.dvd = dvd;
		this.cd = cd;
		this.projector = projector;
		this.screen = screen;
		this.lights = lights;
		this.popper = popper;
	}
 
	public void watchMovie(String movie) {
		System.out.println("Get ready to watch a movie...");
		popper.on();
		popper.pop();
		lights.dim(10);
		screen.down();
		projector.on();
		projector.wideScreenMode();
		amp.on();
		amp.setDvd(dvd);
		amp.setSurroundSound();
		amp.setVolume(5);
		dvd.on();
		dvd.play(movie);
	}
 
 
	public void endMovie() {
		System.out.println("Shutting movie theater down...");
		popper.off();
		lights.on();
		screen.up();
		projector.off();
		amp.off();
		dvd.stop();
		dvd.eject();
		dvd.off();
	}

	public void listenToCd(String cdTitle) {
		System.out.println("Get ready for an audiopile experence...");
		lights.on();
		amp.on();
		amp.setVolume(5);
		amp.setCd(cd);
		amp.setStereoSound();
		cd.on();
		cd.play(cdTitle);
	}

	public void endCd() {
		System.out.println("Shutting down CD...");
		amp.off();
		amp.setCd(cd);
		cd.eject();
		cd.off();
	}

	public void listenToRadio(double frequency) {
		System.out.println("Tuning in the airwaves...");
		tuner.on();
		tuner.setFrequency(frequency);
		amp.on();
		amp.setVolume(5);
		amp.setTuner(tuner);
	}

	public void endRadio() {
		System.out.println("Shutting down the tuner...");
		tuner.off();
		amp.off();
	}
}


public class HomeTheaterTestDrive {
	public static void main(String[] args) {
		Amplifier amp = new Amplifier("Top-O-Line Amplifier");
		Tuner tuner = new Tuner("Top-O-Line AM/FM Tuner", amp);
		DvdPlayer dvd = new DvdPlayer("Top-O-Line DVD Player", amp);
		CdPlayer cd = new CdPlayer("Top-O-Line CD Player", amp);
		Projector projector = new Projector("Top-O-Line Projector", dvd);
		TheaterLights lights = new TheaterLights("Theater Ceiling Lights");
		Screen screen = new Screen("Theater Screen");
		PopcornPopper popper = new PopcornPopper("Popcorn Popper");
 
		HomeTheaterFacade homeTheater = 
				new HomeTheaterFacade(amp, tuner, dvd, cd, 
						projector, screen, lights, popper);
 
		homeTheater.watchMovie("Raiders of the Lost Ark");
		homeTheater.endMovie();
	}
}

HomeTheaterFacade類中的watchMovie()和endMovie()方法等將每項子任務依次處理,對外表現只爲執行一個操作,相當於你按下一個按鈕,就可以開始看電影等操作。


以下是上述類的關係圖:




看到這裏,你應該會覺得,是否可以認爲適配器模式和外觀模式的區別在於:適配器包裝一個類,而外觀模式可以代表許多類?


這樣是不對的!適配器模式將一個或多個類接口變成客戶所期望的一個接口,我們可以適配許多類來提供一個接口讓客戶編碼。

類似的,一個外觀也可以只針對一個擁有複雜接口的類提供簡化的接口。兩種模式的差異,不在於它們“包裝”了幾個類,而是在於它們包裝的意圖。

適配器模式的意圖是,“改變”接口轉換成不同的接口來符合客戶的期望;

而外觀模式的意圖是,提供子系統一個簡化接口,並將客戶從組件的子系統中解耦;

另外,裝飾者模式的意圖是,不改變接口,但加入責任。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章