文章目錄
- 一、影院管理項目
-
- 1.傳統方式解決影院管理
- 2.傳統方式解決問題分析
- 二、外觀模式
-
- 1.基本介紹
- 2.原理類圖
- 三、外觀模式解決影院管理
-
- 1.說明
- 2.代碼
-
- 類圖
- 代碼
- 四、外觀模式的注意事項和細節
一、影院管理項目
組建一個家庭影院
DVD 播放器、投影儀、自動螢幕、環繞立體聲、爆米花機,要求完成使用家庭影院的功能,其過程為:
直接用遙控器:統籌各裝置開關
開爆米花機
放下螢幕
開投影儀
開音響
開 DVD,選 dvd
去拿爆米花
調暗燈光
播放
觀影結束後,關閉各種裝置
1.傳統方式解決影院管理
2.傳統方式解決問題分析
- 在 ClientTest 的 main 方法中,建立各個子系統的對象,并直接去調用子系統(對象)相關方法,會造成調用過程混亂,沒有清晰的過程
- 不利于在 ClientTest 中,去維護對子系統的操作
- 解決思路: 定義一個高層接口,給 子系統中的一組接口提供一個一緻的界面(比如在高層接口提供四個方法ready, play, pause, end ),用來通路子系統中的一群接口
- 也就是說 就是通過定義一個一緻的接口(界面類),用以屏蔽内部子系統的細節,使得調用端隻需跟這個接口發生調用,而無需關心這個子系統的内部細節 => 外觀模式
二、外觀模式
1.基本介紹
- 外觀模式(Facade),也叫“過程模式:外觀模式為子系統中的一組接口 提供一個一緻的界面,此模式定義了一個高層接口,這個接口使得這一子系統更加容易使用
- 外觀模式通過定義一個一緻的接口,用 以屏蔽内部子系統的細節,使得 調用端隻需跟這個接口發生調用,而無需關心這個子系統的内部細節
2.原理類圖
- 外觀類(Facade): 為調用端提供統一的調用接口, 外觀類知道哪些子系統負責處理請求,進而将調用端的請求代理給适當子系統對象
- 調用者(Client): 外觀接口的調用者
- 子系統的集合:指子產品或者子系統,處理 Facade 對象指派的任務,他是功能的實際提供者
三、外觀模式解決影院管理
1.說明
- 外觀模式可以了解為轉換一群接口,客戶隻要調用一個接口,而不用調用多個接口才能達到目的。比如:在 pc上安裝軟體的時候經常有一鍵安裝選項(省去選擇安裝目錄、安裝的元件等等),還有就是手機的重新開機功能(把關機和啟動合為一個操作)。
- 外觀模式就是解決多個複雜接口帶來的使用困難,起到簡化使用者操作的作用
2.代碼
類圖
代碼
/**
* @author: LiDeLin [email protected]
* @date: 2019/11/13
* @description :
*/
public class DVDPlayer {
//使用單例模式 餓漢式
private static DVDPlayer instance = new DVDPlayer();
public static DVDPlayer getInstance(){
return instance;
}
public void open(){
System.out.println("DVD打開");
}
public void off(){
System.out.println("DVD 關閉");
}
public void play(){
System.out.println("DVD播放");
}
//........
public void pause(){
System.out.println("DVD 暫停");
}
}
/**
* @author: LiDeLin [email protected]
* @date: 2019/11/13
* @description :
*/
public class PopCorn {
private static PopCorn instance = new PopCorn();
public static PopCorn getInstance(){
return instance;
}
public void on(){
System.out.println("爆米花 開");
}
public void off(){
System.out.println("PopCorn off");
}
public void pop(){
System.out.println("PopCorn pop");
}
}
/**
* @author: LiDeLin [email protected]
* @date: 2019/11/13
* @description :
*/
public class Projecter {
private static Projecter instance = new Projecter();
public static Projecter getInstance(){
return instance;
}
public void on(){
System.out.println("Projecter 開");
}
public void off(){
System.out.println("Projecter off");
}
public void focus(){
System.out.println("Projecter focus ");
}
}
/**
* @author: LiDeLin [email protected]
* @date: 2019/11/13
* @description :
*/
public class Screen {
private static Screen instance = new Screen();
public static Screen getInstance(){
return instance;
}
public void up(){
System.out.println("Screen 開");
}
public void down(){
System.out.println("Screen off");
}
}
/**
* @author: LiDeLin [email protected]
* @date: 2019/11/13
* @description :
*/
public class Stereo {
private static Stereo instance = new Stereo();
public static Stereo getInstance(){
return instance;
}
public void on(){
System.out.println("Stereo 開");
}
public void of(){
System.out.println("Stereo off");
}
public void up(){
System.out.println("Stereo up");
}
}
/**
* @author: LiDeLin [email protected]
* @date: 2019/11/13
* @description :
*/
public class TheaterLight {
private static TheaterLight instance = new TheaterLight();
public static TheaterLight getInstance(){
return instance;
}
public void on(){
System.out.println("TheaterLight 開");
}
public void of(){
System.out.println("TheaterLight off");
}
public void dim(){
System.out.println("TheaterLight dim");
}
public void birght(){
System.out.println("TheaterLight birght");
}
}
/**
* @author: LiDeLin [email protected]
* @date: 2019/11/13
* @description :
*/
public class HomeTheaterFacade {
//定義各個子系統對象
private TheaterLight theaterLight;
private PopCorn popCorn;
private Stereo stereo;
private Projecter projecter;
private Screen screen;
private DVDPlayer dvdPlayer;
/**
* 構造器
* @param
* @param
* @param
* @param
* @param
* @param
*/
public HomeTheaterFacade() {
this.theaterLight = TheaterLight.getInstance();
this.popCorn = PopCorn.getInstance();
this.stereo = Stereo.getInstance();
this.projecter = Projecter.getInstance();
this.screen = Screen.getInstance();
this.dvdPlayer = DVDPlayer.getInstance();
}
//操作分成四部
public void ready(){
popCorn.on();
popCorn.pop();
screen.down();
projecter.on();
stereo.on();
dvdPlayer.open();
theaterLight.dim();
}
public void play(){
dvdPlayer.play();
}
public void pause(){
dvdPlayer.pause();
}
public void end(){
popCorn.off();
theaterLight.birght();
screen.up();
projecter.off();
dvdPlayer.off();
}
}
/**
* @author: LiDeLin [email protected]
* @date: 2019/11/13
* @description :
*/
public class Client {
public static void main(String[] args) {
//直接調用 很麻煩
//做一個外觀類
HomeTheaterFacade homeTheaterFacade = new HomeTheaterFacade();
homeTheaterFacade.ready();
homeTheaterFacade.play();
homeTheaterFacade.end();
}
}
四、外觀模式的注意事項和細節
- 外觀模式 對外屏蔽了子系統的細節,是以外觀模式降低了用戶端對子系統使用的複雜性
- 外觀模式對用戶端與子系統的耦合關系 - 解耦,讓子系統内部的子產品更易維護和擴充
- 通過合理的使用外觀模式,可以幫我們更好的 劃分通路的 層次
- 當系統需要進行分層設計時,可以考慮使用 Facade 模式
- 在維護一個遺留的大型系統時,可能這個系統已經變得非常難以維護和擴充,此時可以考慮為新系統開發一個Facade 類,來提供遺留系統的比較清晰簡單的接口,讓新系統與 Facade 類互動,提高複用性
- 不能過多的或者不合理的使用外觀模式,使用外觀模式好,還是直接調用子產品好。要以讓系統有層次,利于維護為目的。