圖解Java設計模式之外觀模式 影院管理項目 傳統方式解決影院管理 傳統方式解決影院管理問題分析 外觀模式基本介紹 外觀模式原理類圖 外觀模式解決影院管理 外觀模式的註意事項和細節 影院管理項目 組建一個家庭影院 :DVD 播放器、投影儀、自動屏幕、環繞立體聲、爆米花機,要求完成使用家庭影院的功能, ...
圖解Java設計模式之外觀模式
影院管理項目
組建一個家庭影院 :
DVD 播放器、投影儀、自動屏幕、環繞立體聲、爆米花機,要求完成使用家庭影院的功能,其過程為: 直接用遙控器:統籌各設備開關
開爆米花機
放下屏幕
開投影儀
開音響
開 DVD,選 dvd
去拿爆米花
調暗燈光
播放
觀影結束後,關閉各種設備
傳統方式解決影院管理
傳統方式解決影院管理問題分析
1)在ClientTest的main方法中,創建各個子系統的對象,並直接去調用子系統(對象)相關方法,會造成調用過程混亂,沒有清晰的過程。
2)不利於在ClientTest中,去維護對子系統的操作。
3)解決思路 :定義一個高層介面,給子系統中的一組介面提供一個一致的界面(比如在高層介面提供四個方法ready,play,pause,end),用來訪問子系統中的一群介面
4)也就是說,通過定義一個一致的介面(界面類),用以屏蔽內部子系統的細節,使得調用端只需跟這個介面發生調用,而無需關係這個系統的內部細節 => 外觀模式
外觀模式基本介紹
1)外觀模式(Facade),也叫“過程模式”:外觀模式為子系統中的一組介面提供一個一致的界面,此模式定義類一個高層介面,這個介面使得這一子系統更加容易使用
2)外觀模式通過定義一個一致的介面,用以屏蔽內部子系統的細節,使得調用端只需跟這個介面發生調用,而無需關心這個子系統的內部細節
外觀模式原理類圖
類圖說明 :
1)外觀類(Facade):為調用端提供統一的調用介面,外觀類知道那些子系統負責處理請求,從而將調用端的請求代理給適當子系統對象
2)調用者(Client):外觀介面的調用者
3)子系統的集合 :指模塊或者子系統,處理Facade對象指派的任務,他是功能的實際提供者。
外觀模式解決影院管理
1)外觀模式可以理解為轉換一群介面,客戶只要調用一個介面,而不用調用多個介面才能達到目的。比如 :在pc上安裝軟體的時候經常有一鍵安裝選項(等等),還有手機重啟功能(把關機和啟動合為一個操作)。
2)外觀模式就是解決多個複雜介面帶來的使用困難,起到簡化用戶操作的作用。
package com.example.demo.facade;
public class TheaterLight {
private static TheaterLight instanceLight = new TheaterLight();
public static TheaterLight geTheaterLight() {
return instanceLight;
}
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 ");
}
}
package com.example.demo.facade;
public class Stereo {
private static Stereo instanceStereo = new Stereo();
public static Stereo getStereo() {
return instanceStereo;
}
public void on() {
System.out.println(" Stereo on ");
}
public void off() {
System.out.println(" Stereo off ");
}
public void up() {
System.out.println(" Screen up .. ");
}
}
package com.example.demo.facade;
public class Screen {
private static Screen instanceScreen = new Screen();
public static Screen getInstance() {
return instanceScreen;
}
public void up() {
System.out.println(" Screen up ");
}
public void down() {
System.out.println(" Screen down ");
}
}
package com.example.demo.facade;
public class Projector {
private static Projector instanceProjector = new Projector();
public static Projector getInstance() {
return instanceProjector;
}
public void on() {
System.out.println(" Projector on ");
}
public void off() {
System.out.println(" Projector ff ");
}
public void focus() {
System.out.println(" Projector is focus ");
}
}
package com.example.demo.facade;
public class Popcorn {
private static Popcorn instencePopcorn = new Popcorn();
public static Popcorn getInPopcorn() {
return instencePopcorn;
}
public void on() {
System.out.println(" popcorn on ");
}
public void off() {
System.out.println(" popcorn ff ");
}
public void pop() {
System.out.println(" popcorn is poping ");
}
}
package com.example.demo.facade;
public class DVDPlayer {
private static DVDPlayer instanceDvdPlayer = new DVDPlayer();
public static DVDPlayer getInstance() {
return instanceDvdPlayer;
}
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 ");
}
}
package com.example.demo.facade;
public class HomeTheaterFacade {
private TheaterLight theaterLight;
private Popcorn popcorn;
private Stereo stereo;
private Projector projector;
private Screen screen;
private DVDPlayer dvdPlayer;
public HomeTheaterFacade() {
this.theaterLight = TheaterLight.geTheaterLight();
this.dvdPlayer = DVDPlayer.getInstance();
this.popcorn = Popcorn.getInPopcorn();
this.projector = Projector.getInstance();
this.screen = Screen.getInstance();
this.stereo = Stereo.getStereo();
}
// 操作分成四部
public void ready() {
popcorn.on();
popcorn.pop();
screen.down();
projector.on();
stereo.on();
dvdPlayer.on();
theaterLight.dim();
}
public void play() {
dvdPlayer.play();
}
public void pause() {
dvdPlayer.play();
}
public void end() {
popcorn.off();
theaterLight.bright();
screen.up();
projector.off();
stereo.off();
dvdPlayer.off();
}
}
package com.example.demo.facade;
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
HomeTheaterFacade homeTheaterFacade = new HomeTheaterFacade();
homeTheaterFacade.ready();
homeTheaterFacade.play();
}
}
外觀模式的註意事項和細節
1)外觀模式對外屏蔽了子系統的細節,因此外觀模式降低了客戶端對子系統使用的複雜性
2)外觀模式對客戶端與子系統的耦合關心 - 解耦,讓子系統內部的模塊更易維護和擴展
3)通過合理的使用外觀模式,可以幫我們更好的劃分訪問的層次
4)當系統需要進行分層設計時,可以考慮使用Facade模式
5)在維護一個遺留的大型系統時,可能這個系統已經變得非常難以維護和擴展,此時可以考慮為新系統開發一個Facade類,來提供遺留系統的比較清晰簡單的介面,讓新系統與Facade類交互,提高復用性
6)不能過多的或者不合理的使用外觀模式,使用外觀模式好,還是直接調用模塊好。要以讓系統有層次,利於維護為目的。