文章目錄
當一個系統的功能越來越強,子系統會越來越多,客戶對系統的訪問也變得越來越複雜。這時如果系統內部發生改變,客戶端也要跟着改變,這違背了“開閉原則”,也違背了“迪米特法則”,所以有必要爲多個子系統提供 一個統一的接口 ,從而降低系統的耦合度,這就是外觀模式的目標。
客戶去房產局辦理房產證過戶要遇到的部門和窗口:
一、外觀模式的定義與特點
定義:
外觀模式,是一種通過爲多個複雜的子系統提供 一個一致的接口 ,而使這些子系統更加容易被訪問的模式。該模式對外有一個統一接口,外部應用程序不用關心內部子系統的具體的細節,這樣會大大降低應用程序的複雜度,提高了程序的可維護性。
優點:
- 降低了子系統與客戶端之間的耦合度,使得子系統的變化不會影響調用它的客戶類。
- 對客戶屏蔽了子系統組件,減少了客戶處理的對象數目,並使得子系統使用起來更加容易。
- 降低了大型軟件系統中的編譯依賴性,簡化了系統在不同平臺之間的移植過程,因爲編譯一個子系統不會影響其他的子系統,也不會影響外觀對象。
缺點:
- 不能很好地限制客戶使用子系統類。
- 增加新的子系統可能需要修改外觀類或客戶端的源代碼,違背了“開閉原則”。
二、UML類圖
外觀模式的結構比較簡單,主要是定義了一個高層接口。它包含了對各個子系統的引用,客戶端可以通過它訪問各個子系統的功能。現在來分析其基本結構和實現方法。
外觀模式包含以下主要角色:
- Facade(外觀):爲多個
SubSystem
對外提供一個共同的接口。 - SubSystem(子系統):實現系統的部分功能,客戶可以通過外觀角色訪問它。
- 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();
}
}