专栏首页关忆北.设计模式之外观(门面)模式

设计模式之外观(门面)模式

外观(门面)模式

外观模式(Facade),他隐藏了系统的复杂性,并向客户端提供了一个可以访问系统的接口。这种类型的设计模式属于结构性模式。为子系统中的一组接口提供了一个统一的访问接口,这个接口使得子系统更容易被访问或者使用。类似的实际例子有消息中间件,把一个数据丢到消息中间件,谁需要,谁去消息后中间件去拿。这种设计模式可以用于解耦。

我们举个栗子,你要去工厂制造一辆汽车,你需要先从门口去一楼制造引擎,再从门口去二楼制造底盘,最后从门口去五楼制造变速箱,然后去四楼制造轮胎,这样整个流程会特别繁琐,外观模式就提供一个门面接口(Facade),门面内把原来的逻辑流程进行封装,你只需要从门口去到这个门面,门面内部分工帮你去管理汽车的制造流程。回归代码世界,如果我们不使用门面模式,需要调用发动机制造的对象、底盘制造的对象变速箱制造的对象等等,这样你的业务逻辑便显得杂乱无章并且代码各个子系统之间的耦合度很高,显然这样做不是最优方案。

门面解决方案:

将汽车制造流程逻辑进行封装,只提供一个汽车制造接口,当客户访问汽车接口(Facade)时,工厂内部流水线制造组装完成一辆用户所需的汽车。这样做的优点就是:把多个对象之间的调用交互变为一个对象与一个接口之间的交互,降低代码耦合度。与用户分别调用子系统模块相比,客户不能自己定义引擎、底盘等配件的型号,所以门面模式提供的功能有限,但是它可以快速且简便的提供客户真正关心的需求。

talk is cheaper,show me your code.

假设我们有一个需求:将ogg格式的视频文件转换为mp4格式,那么我们需要读取ogg格式的文件流,将流转换为音频流、视频流,写入文件,再进行音频流、视频流组合,最后完成转换,当然我们可以单个流程进行调用,下面的代码中有两种方式的具体体现。

代码已经开源至Github https://github.com/FirstMrRight/Design_pattern

Codec.java

/**
 * @author  Liutx
 * @date  2020/12/26 22:37
 * @Description 解码器接口
 */
public interface Codec {
}

MPEG4CompressionCodec.java

/**
 * @author Liutx
 * @date 2020/12/26 22:38
 * @Description MPEG4解码器
 */
public class MPEG4CompressionCodec implements Codec {

    /**
     * 该解码器能够行使的功能
     */
    public String type = "mp4";
}

OggCompressionCodec.java

/**
 * @author Liutx
 * @date 2020/12/26 22:40
 * @Description ogg解码器
 */
public class OggCompressionCodec implements Codec {
    public String type = "ogg";
}

BitrateReader.class

/**
 * @author Liutx
 * @date 2020/12/26 22:48
 * @Description 字节读取转换为Video
 */
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;
    }

}

AudioMixer.java

/**
 * @author Liutx
 * @date 2020/12/26 22:50
 * @Description 混音器,组合视频、音频
 */
public class AudioMixer {
    public File fix(VideoFile result){
        System.out.println("AudioMixer: fixing audio...");
        return new File("tmp");
    }
}

VideoFile.java

/**
 * @author Liutx
 * @date 2020/12/26 22:33
 * @Description
 */
public class VideoFile {
    private String name;
    private String codecType;

    public VideoFile(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCodecType() {
        return codecType;
    }

    public void setCodecType(String codecType) {
        this.codecType = codecType;
    }
}

VideoConversionFacade.java

/**
 * @author Liutx
 * @date 2020/12/26 22:58
 * @Description 门面模式封装内部流程、对外提供接口
 */
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;
    }
}

ClientDemo.java (调用)

public class ClientDemo {
    public static void main(String[] args) {
        VideoConversionFacade converter = new VideoConversionFacade();
        File mp4Video = converter.convertVideo("video.ogg", "mp4");


        System.out.println("===================================");


        VideoFile file = new VideoFile("video.ogg");
        CodecFactory.extract(file);
        BitrateReader.read(file,new OggCompressionCodec());
        BitrateReader.convert(file,new MPEG4CompressionCodec());
        AudioMixer audioMixer = new AudioMixer();
        audioMixer.fix(file);
    }
}

Console 输出:

VideoConversionFacade: conversion started.
CodecFactory: extracting ogg audio...
BitrateReader: reading file...
BitrateReader: writing file...
AudioMixer: fixing audio...
VideoConversionFacade: conversion completed.
===================================
CodecFactory: extracting ogg audio...
BitrateReader: reading file...
BitrateReader: writing file...
AudioMixer: fixing audio...

总结: 使用门面模式可以非常优雅的实现代码的调用,当然我们也可以自己使用单独调用对象的方式实现相同的功能,但是这种方式不仅显得代码杂乱无章,而且这种方式一看就非常不环保。

本文参与 腾讯云自媒体分享计划 ,欢迎热爱写作的你一起参与!
本文分享自作者个人站点/博客:https://blog.csdn.net/weixin_42313773复制
如有侵权,请联系 cloudcommunity@tencent.com 删除。
登录 后参与评论
0 条评论

相关文章

  • 设计模式系列| 外观(门面)模式

    外观模式是一种结构型设计模式, 能为程序库、 框架或其他复杂类提供一个简单的接口。

    狼王编程
  • 真实案例实战——设计模式之【外观模式(门面模式)】

    须臾之余
  • Java 设计模式系列(13) —— 外观模式(门面模式)

    外观模式的定义: 要求一个子系统的外部预期内部的通信必须通过一个统一的对象进行,外观模式提供了一个高层次的接口,使得子系统更容易使用

    求和小熊猫
  • 设计模式第六讲-外观模式(门面模式)

    外观模式(Facade,门面模式), 为子系统中额外一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

    用户2825413
  • 前端的设计模式系列-外观(门面)模式

    代码也写了几年了,设计模式处于看了忘,忘了看的状态,最近对设计模式有了点感觉,索性就再学习总结下吧。

    windliang
  • 外观模式 门面模式 Facade 创建型 设计模式(十三)

    随着项目的持续发展,系统基本上都是会往功能更全面的方向发展,那么也就意味着我们的系统将会变得更加复杂。

    noteless
  • Java外观模式(门面模式Facade)

      外观模式也叫门面模式,是开发过程中使用频率非常高的一种设计模式,但非常容易理解。

    用户4919348
  • [PHP]外观/门面/Facade模式-结构型设计模式

    外观(Facade)模式又叫作门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程...

    大灰狼2
  • 设计模式之 外观模式

    外观模式(又称门面模式),通过外观的包装,使应用程序只能看到外观对象,而不会看到具体的细节对象,这样无疑会降低应用程序的复杂度,并且提高了程序的可维护性。UML...

    BUG弄潮儿
  • 设计模式~门面模式

    在门面模式中,通常只需要一个门面类,并且此门面类只有一个实例,也就是说,它是一个单例类。

    Vincent-yuan
  • 设计模式-门面模式

    cwl_java
  • 设计模式之十(外观模式)

    外观模式:为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一系统更加容易使用.

    aehyok
  • 漫画:设计模式之 “外观模式”

    于是肯德基对这些菜品做了一定的组合,推出了各种各样的套餐。比如A套餐,包括汉堡/薯条/可乐;B套餐,包括汉堡/鸡翅/沙拉/可乐:

    小灰
  • Java设计模式之(九)——门面模式

    门面模式(Facade Pattern):也叫外观模式,要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。 门面模式提供一个高层次的接口,使得子系统...

    IT可乐
  • 【设计模式-门面模式】

    学校的学生信息相关系统大家都用过,比如门户网、教务系统、图书管理系统等,一般需要用到某个系统,需要单独去登录,比如同时想去门户网和教务系统查询信息,需要在两个网...

    Liusy
  • 设计模式--外观模式

    最少知识原则:尽量减少对象之间的交互,只留几个“密友” 项目设计中就是不要让太多的类耦合在一起

    HUC思梦
  • 【设计模式】外观模式

    外观模式也叫门面模式,主要解决的是降低调用方的使用接口的复杂逻辑组合。这样调用方与实际的接口提供方提供方提供了一个中间层,用于包装逻辑提供API接口。有些时候外...

    Li_XiaoJin
  • Java 设计模式 之 facade(外观)设计模式

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://louluan.blog.c...

    亦山
  • 设计模式实战-门面模式

    本小节我们要学习的设计模式叫做外观模式,也叫做门面模式 Facade。想象一下,我们系统随着时间的推移,系统复杂性、类之间的相互调用会变得越来越多,相比较客户角...

    架构师修炼

扫码关注腾讯云开发者

领取腾讯云代金券