使用示例:使用 Java 开发的程序中经常会使用外观模式。 它在与复杂程序库和 API 协作时特别有用。
下面是一些核心 Java 程序库中的外观示例:
javax.faces.context.FacesContext
在底层使用了LifeCycle
、ViewHandler
和NavigationHandler
这几个类, 但绝大多数客户端不知道。javax.faces.context.ExternalContext
在内部使用了ServletContext
、HttpSession
、HttpServletRequest
、HttpServletResponse
和其他一些类。
识别方法:外观可以通过使用简单接口, 但将绝大部分工作委派给其他类的类来识别。 通常情况下, 外观管理着其所使用的对象的完整生命周期。
01复杂视频转换库的简单接口
在本例中, 外观简化了复杂视频转换框架所进行的沟通工作。
外观提供了仅包含一个方法的类, 可用于处理对框架中所需类的配置与以正确格式获取结果的复杂工作。
02some_complex_media_library: 复杂视频转换程序库
some_complex_media_library/VideoFile.java
package refactoring_guru.facade.example.some_complex_media_library; 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.java
package refactoring_guru.facade.example.some_complex_media_library; public interface Codec { }
some_complex_media_library/MPEG4CompressionCodec.java
package refactoring_guru.facade.example.some_complex_media_library; public class MPEG4CompressionCodec implements Codec { public String type = "mp4"; }
some_complex_media_library/OggCompressionCodec.java
package refactoring_guru.facade.example.some_complex_media_library; public class OggCompressionCodec implements Codec { public String type = "ogg"; }
some_complex_media_library/CodecFactory.java
package refactoring_guru.facade.example.some_complex_media_library; 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 refactoring_guru.facade.example.some_complex_media_library; 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 refactoring_guru.facade.example.some_complex_media_library; import java.io.File; public class AudioMixer { public File fix(VideoFile result){ System.out.println("AudioMixer: fixing audio..."); return new File("tmp"); } }
03facade
facade/VideoConversionFacade.java: 外观提供了进行视频转换的简单接口
package refactoring_guru.facade.example.facade; import refactoring_guru.facade.example.some_complex_media_library.*; import java.io.File; 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 MPEG4CompressionCodec(); } else { destinationCodec = new OggCompressionCodec(); } 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 refactoring_guru.facade.example; import refactoring_guru.facade.example.facade.VideoConversionFacade; import java.io.File; public class Demo { public static void main(String[] args) { VideoConversionFacade converter = new VideoConversionFacade(); File mp4Video = converter.convertVideo("youtubevideo.ogg", "mp4"); // ... } }
OutputDemo.txt: 执行结果
VideoConversionFacade: conversion started. CodecFactory: extracting ogg audio... BitrateReader: reading file... BitrateReader: writing file... AudioMixer: fixing audio... VideoConversionFacade: conversion completed.