爲子系統中的一組接口提供一個一致的界面,Facade模式定義了一個高層接口,這個接口使得這一子系統更加容易使用java
將一個系統劃分紅若干個子系統有利於下降系統的複雜性。一個常見的設計目標是使子系統間的通訊和相互依賴關係達到最小。達到該目標的途徑之一就是引入一個外觀對象,他爲子系統中較通常的設施提供了一個單一而簡單的界面程序員
例若有一個編程環境,它容許應用程序訪問它的編譯子系統。這個編譯子系統包含了若干個類來實現這一編譯器,如Scanner,Parser,ProgramNode,BytecodeStream和ProgramNodeBuilder。可是對於大多數編譯器的用戶並不關心語法分析和代碼生成這樣的細節,他們只是但願編譯一些代碼。編譯子系統提供了一個Compiler類,這個類定義了一個編譯器功能的統一接口。Compiler類是一個外觀,它給用戶提供了一個單一而簡單的編譯子系統接口。編譯器的外觀能夠方便大多數程序員使用,同時對少數懂得如何使用底層功能的人,它並不隱藏這些功能編程
1) 它對客戶屏蔽子系統組件,於是減小了客戶處理的對象數目並使得子系統使用起來更加方便緩存
2) 實現了子系統和客戶之間的鬆耦合關係,而子系統內部的功能組件每每是緊耦合的。鬆耦合關係使得子系統的組件變化不會影響到它的客戶。Facade模式有助於創建層次結構系統,也有助於對對象之間的依賴關係分層。Facade模式能夠消除複雜的循環依賴關係ide
3) 若是須要,該模式並不限制使用子系統類ui
some_complex_media_library/VideoFile.javathis
package facade.some_complex_media_library; /** * @author GaoMing * @date 2021/7/19 - 20:59 */ public class VideoFile { private String name; private String codecType; public VideoFile(String name) { this.name = name; this.codecType = name.substring(name.indexOf(".") + 1); } public String getCodecType() { return codecType; } public String getName() { return name; } }
some_complex_media_library/Codec.javaspa
package facade.some_complex_media_library; /** * @author GaoMing * @date 2021/7/19 - 20:59 */ public interface Codec { }
some_complex_media_library/MPEG4CompressionCodec.java設計
package facade.some_complex_media_library; /** * @author GaoMing * @date 2021/7/19 - 21:00 */ public class MPEG4CompressionCodec implements Codec{ public String type = "mp4"; }
some_complex_media_library/OggCompressionCodec.java代理
package facade.some_complex_media_library; /** * @author GaoMing * @date 2021/7/19 - 21:00 */ public class OggCompressionCodec implements Codec{ public String type = "ogg"; }
some_complex_media_library/CodecFactory.java
package facade.some_complex_media_library; /** * @author GaoMing * @date 2021/7/19 - 21:01 */ public class CodecFactory { public static Codec extract(VideoFile file) { String type = file.getCodecType(); if (type.equals("mp4")) { System.out.println("CodecFactory: extracting mpeg audio..."); return new MPEG4CompressionCodec(); } else { System.out.println("CodecFactory: extracting ogg audio..."); return new OggCompressionCodec(); } } }
some_complex_media_library/BitrateReader.java
package facade.some_complex_media_library; /** * @author GaoMing * @date 2021/7/19 - 21:01 */ public class BitrateReader { public static VideoFile read(VideoFile file, Codec codec) { System.out.println("BitrateReader: reading file..."); return file; } public static VideoFile convert(VideoFile buffer, Codec codec) { System.out.println("BitrateReader: writing file..."); return buffer; } }
some_complex_media_library/AudioMixer.java
package facade.some_complex_media_library; import java.io.File; /** * @author GaoMing * @date 2021/7/19 - 21:01 */ public class AudioMixer { public File fix(VideoFile result){ System.out.println("AudioMixer: fixing audio..."); return new File("tmp"); } }
facade/VideoConversionFacade.java: 外觀提供了進行視頻轉換的簡單接口
package facade.facade; import facade.some_complex_media_library.*; import java.io.File; /** * @author GaoMing * @date 2021/7/19 - 21:02 */ public class VideoConversionFacade { public File convertVideo(String fileName, String format) { System.out.println("VideoConversionFacade: conversion started."); VideoFile file = new VideoFile(fileName); Codec sourceCodec = CodecFactory.extract(file); Codec destinationCodec; if (format.equals("mp4")) { destinationCodec = new OggCompressionCodec(); } else { destinationCodec = new MPEG4CompressionCodec(); } VideoFile buffer = BitrateReader.read(file, sourceCodec); VideoFile intermediateResult = BitrateReader.convert(buffer, destinationCodec); File result = (new AudioMixer()).fix(intermediateResult); System.out.println("VideoConversionFacade: conversion completed."); return result; } }
Demo.java: 客戶端代碼
package facade; import facade.facade.VideoConversionFacade; import java.io.File; /** * @author GaoMing * @date 2021/7/19 - 20:59 */ public class Demo { public static void main(String[] args) { VideoConversionFacade converter = new VideoConversionFacade(); File mp4Video = converter.convertVideo("youtubevideo.ogg", "mp4"); // ... } }
執行結果
VideoConversionFacade: conversion started.
CodecFactory: extracting ogg audio...
BitrateReader: reading file...
BitrateReader: writing file...
AudioMixer: fixing audio...
VideoConversionFacade: conversion completed.
外觀和中介者模式的職責相似:它們都嘗試在大量緊密耦合的類中組織起合做
- 外觀爲子系統中的全部對象定義了一個簡單接口, 可是它不提供任何新功能。子系統自己不會意識到外觀的存在。子系統中的對象能夠直接進行交流
- 中介者將系統中組件的溝通行爲中心化。各組件只知道中介者對象, 沒法直接相互交流
識別方法:外觀能夠經過使用簡單接口,但將絕大部分工做委派給其餘類的類來識別。一般狀況下,外觀管理着其所使用的對象的完整生命週期