摘要:改變接口的新模式,為了簡化接口這次帶來的模式為外觀模式,之所以這么稱呼,因為它將一個或多個類復雜的一切都隱藏起來。
改變接口的新模式,為了簡化接口
這次帶來的模式為外觀模式,之所以這么稱呼,因為它將一個或多個類復雜的一切都隱藏起來。
我依舊舉生活中例子,現在有些朋友家的液晶電視可能是大尺寸的,或者有用投影儀來看電視,打游戲的。有一天我想用家庭影院系統在家里看一次大片。
1、打開爆米花機 2、開始爆米花 3、將燈光調暗 4、放下屏幕 5、打開投影儀 6、將投影儀的輸入切換到DVD 7、將投影儀設置在寬屏模式下 8、打開功放 9、將功放的輸入設置為DVD 10、將功放的設置為環繞立體聲 11、功放音量調到中(5) 12、打開DVD播放器 13、開始播放DVD
等我操作完這些我才能開始享受大片,需要打開這么多開關。。而且如果看完要關閉是不是又要反向把動作再來一遍,這樣或許連我都沒興趣使用影院系統了。也許這套系統該升級了!!
這時候外觀模式就發揮作用了,通過實現一個提供更合理的接口的外觀類,讓一個復雜的系統變得使用簡單了,
我們來看看外觀是怎么運作的。如圖(可點擊查看原圖)
這里注意:
1、外觀不只是簡化了接口,也將客戶從組件的子系統中解耦,若客戶有需要還是可以使用子系統,外觀是為了簡化接口。
2、外觀和適配器模式可以包裝許多類,但是外觀的意圖是簡化接口,而適配器的意圖是將接口轉換成不同的接口,換句話說是讓兩個原本不適用的東西,變得能相互使用一樣。
現在開始我們的家庭影院系統升級把~~~~
家庭影院類(外觀)
package headfirst.facade.hometheater; /** * 家庭影院 (將各個組件統一的“接口”) * * @author Joy * */ // 外觀類 public class HomeTheaterFacade { /** * 組合,將用到的子系統組件全部都在這里 */ Amplifier amp;// 擴音器 Tuner tuner;// 無線電收音機 DvdPlayer dvd;// DVD播放器 CdPlayer cd;// 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; } /** * 將子系統的組件整合成一個統一的接口 watchMovie()方法 就相當于把所有操作放在一個方法里,簡化操作 * 將我們之前手動進行的每項任務我依次處理。 注意:每項任務都是具體實現都是委托子系統中相應的組件處理的 * * @param movie */ public void watchMovie(String movie) { System.out.println("準備好,看電影了..."); 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); } /** * endMovie() 負責關閉一切,每項任務也都是委托子系統中對應組件的具體方法 */ public void endMovie() { System.out.println("關閉電影..."); popper.off(); lights.on(); screen.up(); projector.off(); amp.off(); dvd.stop(); dvd.eject(); dvd.off(); } /** * 下面這項方法,若客戶還是需要調用子系統的方法話,相應調用即可 * * @param cdTitle */ 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(); } }
下面是各個組件類(子系統)
package headfirst.facade.hometheater; /** * 擴音器類 * * @author Joy * */ public class Amplifier { // 音響類型 String description; Tuner tuner; DvdPlayer dvd; CdPlayer cd; public Amplifier(String description) { this.description = description; } public void on() { System.out.println(description + " 開啟"); } public void off() { System.out.println(description + " 關閉"); } public void setStereoSound() { System.out.println(description + " 環繞立體模式"); } public void setSurroundSound() { System.out.println(description + " 環繞聲設置(5 音量, 1 低音炮)"); } public void setVolume(int level) { System.out.println(description + " 設置音量: " + level); } public void setTuner(Tuner tuner) { System.out.println(description + "設置音效 " + dvd); this.tuner = tuner; } public void setDvd(DvdPlayer dvd) { System.out.println(description + " 設置DVD播放器 " + dvd); this.dvd = dvd; } public void setCd(CdPlayer cd) { System.out.println(description + " 設置CD播放器" + cd); this.cd = cd; } public String toString() { return description; } }
package headfirst.facade.hometheater; /** * CD播放器 * * @author Joy * */ public class CdPlayer { String description; int currentTrack; Amplifier amplifier; String title; public CdPlayer(String description, Amplifier amplifier) { this.description = description; this.amplifier = amplifier; } public void on() { System.out.println(description + " 開啟"); } public void off() { System.out.println(description + " 關閉"); } public void eject() { title = null; System.out.println(description + " 彈出"); } public void play(String title) { this.title = title; currentTrack = 0; System.out.println(description + " 播放 "" + title + """); } public String toString() { return description; } }
package headfirst.facade.hometheater; /** * DVD播放器 * * @author Joy * */ public class DvdPlayer { String description; int currentTrack; Amplifier amplifier; String movie; public DvdPlayer(String description, Amplifier amplifier) { this.description = description; this.amplifier = amplifier; } public void on() { System.out.println(description + " 開啟"); } public void off() { System.out.println(description + " 關閉"); } public void eject() { movie = null; System.out.println(description + " 彈出"); } public void play(String movie) { this.movie = movie; currentTrack = 0; System.out.println(description + " 播放 "" + movie + """); } public void play(int track) { if (movie == null) { System.out.println(description + " can"t play track " + track + " no dvd inserted"); } else { currentTrack = track; System.out.println(description + " playing track " + currentTrack + " of "" + movie + """); } } public void stop() { currentTrack = 0; System.out.println(description + " 停止 "" + movie + """); } public String toString() { return description; } }
package headfirst.facade.hometheater; /** * 爆米花機類 * * @author Joy * */ public class PopcornPopper { String description; public PopcornPopper(String description) { this.description = description; } public void on() { System.out.println(description + " 開啟"); } public void off() { System.out.println(description + " 關閉"); } public void pop() { System.out.println(description + "正在工作!"); } public String toString() { return description; } }
package headfirst.facade.hometheater; /** * 投影儀類 * @author Joy * */ public class Projector { String description; DvdPlayer dvdPlayer; public Projector(String description, DvdPlayer dvdPlayer) { this.description = description; this.dvdPlayer = dvdPlayer; } public void on() { System.out.println(description + " 開啟"); } public void off() { System.out.println(description + " 關閉"); } public void wideScreenMode() { System.out.println(description + " 設置成寬屏模式 (16x9 高寬比)"); } public void tvMode() { System.out.println(description + " 設置為TV模式 (4x3 高寬比)"); } public String toString() { return description; } }
package headfirst.facade.hometheater; /** * 屏幕類 * * @author Joy * */ public class Screen { String description; public Screen(String description) { this.description = description; } public void up() { System.out.println(description + " 上升"); } public void down() { System.out.println(description + " 降下"); } public String toString() { return description; } }
package headfirst.facade.hometheater; /** * 影院燈光 * * @author Joy * */ public class TheaterLights { String description; public TheaterLights(String description) { this.description = description; } public void on() { System.out.println(description + " 打開"); } public void off() { System.out.println(description + " 關閉"); } public void dim(int level) { System.out.println(description + " 掉亮度為: " + level + "%"); } public String toString() { return description; } }
package headfirst.facade.hometheater; public class Tuner { String description; Amplifier amplifier; double frequency; public Tuner(String description, Amplifier amplifier) { this.description = description; } public void on() { System.out.println(description + " on"); } public void off() { System.out.println(description + " off"); } public void setFrequency(double frequency) { System.out.println(description + " setting frequency to " + frequency); this.frequency = frequency; } public String toString() { return description; } }
測試類(用輕松方式看電影)
package TestMain; import headfirst.facade.hometheater.Amplifier; import headfirst.facade.hometheater.CdPlayer; import headfirst.facade.hometheater.DvdPlayer; import headfirst.facade.hometheater.HomeTheaterFacade; import headfirst.facade.hometheater.PopcornPopper; import headfirst.facade.hometheater.Projector; import headfirst.facade.hometheater.Screen; import headfirst.facade.hometheater.TheaterLights; import headfirst.facade.hometheater.Tuner; /** * 外觀作用簡化接口 * 適配器作用是將接口能與另一個接口相匹配 * * @author Joy * */ public class HomeTheaterTestDrive { public static void main(String[] args) { // 將各個組件都實例化 Amplifier amp = new Amplifier("Top-O-Line 擴音器"); Tuner tuner = new Tuner("Top-O-Line AM/FM 調諧器", amp); DvdPlayer dvd = new DvdPlayer("Top-O-Line DVD 播放器", amp); CdPlayer cd = new CdPlayer("Top-O-Line CD 播放器", amp); Projector projector = new Projector("Top-O-Line 投影儀", dvd); TheaterLights lights = new TheaterLights("影院天花板燈"); Screen screen = new Screen("影院屏幕"); PopcornPopper popper = new PopcornPopper("爆米花機"); // 實例化外觀 HomeTheaterFacade homeTheater = new HomeTheaterFacade(amp, tuner, dvd, cd, projector, screen, lights, popper); // 使用簡化的開啟關閉接口 homeTheater.watchMovie("《奪寶奇兵》"); homeTheater.endMovie(); } }
效果圖
是不是感到很輕松了,我只需要“放入”我想看的電影,剩下一切程序自動化完成。
外觀模式定義:提供了一個統一的接口,用來訪問子系統中的一群接口。外觀定義了一個高層接口,讓子系統更容易使用。
再來一張圖來理解外觀
這里就引出一個“最少知識”原則
最少知識原則告訴我們要減少對象之間的交互,只留下幾個“密友”,當你在設計一個系統的時候,,不管是任何對象,都要注意它所交互的類有哪些,并注意它和這些類是如何交互的。
這個原則希望我們設計中,不要讓太多的類耦合在一起,免得修改系統一部分,就會影響到其他部分。如果許多類之間相互依賴,那么系統就會變得牽一發而動全身了也因為要復雜而不容易被人理解。
要點:
1、當需要簡化并統一一個很大的接口或者一群復雜的接口時,使用外觀。
2、外觀將客戶從一個復雜的子系統中解耦出來。
3、實現一個外觀,將子系統組合委托給外觀,然后外觀將工作讓子系統執行。
感謝你看到這里,外觀模式到這里就結束了,本人文筆隨便,若有不足或錯誤之處望給予指點,90度彎腰~~~很快我會發布下一個設計模式的內容,生命不息,編程不止!
參考書籍:《Head First 設計模式》
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/70457.html
摘要:外觀模式外觀模式是指提供一個統一的接口去訪問多個子系統的多個不同的接口,為子系統中的一組接口提供統一的高層接口。外觀模式在我們的日常工作中十分常見。 外觀模式 外觀模式是指提供一個統一的接口去訪問多個子系統的多個不同的接口,為子系統中的一組接口提供統一的高層接口。使得子系統更容易使用,不僅簡化類中的接口,而且實現調用者和接口的解耦。外觀模式在我們的日常工作中十分常見。 我們來看一個例子...
摘要:設計模式的定義在面向對象軟件設計過程中針對特定問題的簡潔而優雅的解決方案。從前由于使用的局限性,和做的應用相對簡單,不被重視,就更談不上設計模式的問題。 ‘從大處著眼,從小處著手’,以前對這句話一知半解,自從踏出校門走入社會,開始工作以來,有了越來越深的理解,偶有發現這句話用在程序開發中也有用,所以,近段時間開始嘗試著分析jQuery源碼,分析angularjs源碼,學習設計模式。 設...
摘要:可能很多人和我一樣首次聽到前端架構這個詞第一反應是前端還有架構這一說呢在后端開發領域系統規劃和可擴展性非常關鍵因此架構師備受重視早在開發工作啟動之前他們就被邀請加入到項目中而且他們會跟客戶討論即將建成的平臺的架構要求使用還什么技術棧內容類型 可能很多人和我一樣, 首次聽到前端架構這個詞, 第一反應是: 前端還有架構這一說呢? 在后端開發領域, 系統規劃和可擴展性非常關鍵, 因此架構師備...
摘要:可能很多人和我一樣首次聽到前端架構這個詞第一反應是前端還有架構這一說呢在后端開發領域系統規劃和可擴展性非常關鍵因此架構師備受重視早在開發工作啟動之前他們就被邀請加入到項目中而且他們會跟客戶討論即將建成的平臺的架構要求使用還什么技術棧內容類型 可能很多人和我一樣, 首次聽到前端架構這個詞, 第一反應是: 前端還有架構這一說呢? 在后端開發領域, 系統規劃和可擴展性非常關鍵, 因此架構師備...
閱讀 940·2021-09-27 13:36
閱讀 888·2021-09-08 09:35
閱讀 1064·2021-08-12 13:25
閱讀 1437·2019-08-29 16:52
閱讀 2907·2019-08-29 15:12
閱讀 2726·2019-08-29 14:17
閱讀 2606·2019-08-26 13:57
閱讀 1012·2019-08-26 13:51