• 11【门面设计模式】



    十一、门面设计模式

    11.1 门面设计模式简介

    11.1.1 门面设计模式概述

    门面模式(Facade Pattern):也叫外观设计模式,该模式对外有一个统一接口,用来访问子系统中的一群接口,外部应用程序不用关心内部子系统的具体的细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。

    其实我们在写代码时,有意无意的都在大量的使用门面设计模式,但凡高层模块需要调度多个子系统时,我们都会自觉的创建一个新类来封装这些子系统,提供精简的调用方式,让高层模块可以更加容易地间接调用这些子系统的功能;包括我们以前编写的Utils工具类、拦截器、过滤器、网关等都是提供一个调用入口,由这些门面来负责调用复杂的子系统;

    门面设计模式主要解决的问题就是:降低访问复杂系统的内部子系统时的复杂度,简化客户端之间的接口。

    Tips:门面设计模式就是迪米特法则的具体应用;

    11.1.2 门面设计模式中的角色

    门面设计模式具备如下几个角色:

    • 1)门面角色(Facade):各子系统对外的统一接口,整合各个子系统;
    • 2)子系统角色(SubSystem):实现系统的部分功能,客户通过Facade访问它。

    11.2 门面设计模式的实现

    【案例】

    照顾小孩子需要负责小孩子的饮食起居,包括做饭,洗衣服,遛孩子等等…带一个小孩子非常麻烦,于是我们请到一个保姆来帮助我们干这些事情;

    UML类图如下:

    在这里插入图片描述

    • 子系统角色1-照顾小孩类:
    package com.patter.demo;
    
    /**
     * @author lscl
     * @version 1.0
     * @intro: 带孩子-子系统
     */
    public class CareChild {
        public void doCareChild(String destName) {
            System.out.println("遛孩子,带孩子【" + destName + "】...");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 子系统角色2-做饭类:
    package com.patter.demo;
    
    /**
     * @author lscl
     * @version 1.0
     * @intro: 做饭-子系统
     */
    public class Cooking {
    
        public void doCooking(String menu) {
            System.out.println("【给孩子吃" + menu + "】");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 子系统角色3-洗衣服类:
    package com.patter.demo;
    
    /**
     * @author lscl
     * @version 1.0
     * @intro: 换洗衣服-子系统
     */
    public class Laundry {
        public void doLaundry(){
            System.out.println("帮孩子换洗衣服...");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 门面角色-保姆类:
    package com.patter.demo;
    
    /**
     * @author lscl
     * @version 1.0
     * @intro: 保姆-门面角色
     */
    public class BabySister {
    
        private CareChild careChild = new CareChild();
        private Cooking cooking = new Cooking();
        private Laundry laundry = new Laundry();
    
        // 带孩子经费
        private Double money = 4000.0D;
    
        public BabySister(Double money) {
            this.money = money;
        }
    
        public BabySister() {
        }
    
        /**
         * 带孩子
         */
        public void careChild() {
    
            if (money < 5000.0D) {
                careChild.doCareChild("省内游");
            } else if (money >= 5000 && money < 8000) {
                careChild.doCareChild("国内游");
            } else if (money >= 8000) {
                careChild.doCareChild("全球游");
            }
        }
    
        /**
         * 做饭
         */
        public void cooking() {
            if (money < 5000) {
                cooking.doCooking("大白菜,豆芽菜");
            } else if (money >= 5000 && money < 8000) {
                cooking.doCooking("小青菜,辣椒炒肉");
            } else if (money >= 8000) {
                cooking.doCooking("小青菜,辣椒炒肉,糖醋排骨");
            }
    
        }
    
        /**
         * 洗衣服
         */
        public void laundry() {
            laundry.doLaundry();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    11.3 门面设计模式的优缺点

    门面设计模式和我们之前的代理设计模式有些许类似,但是却有本质上的不同,代理设计模式主要关注的是对一个类的增强或保护,门面设计模式则是对多个子系统的统一管理;

    • 优点:
      • 1)简化系统的调用过程,用户不需要对子系统有很深的了解,以免给子系统带来风险,符合迪米特法则
      • 2)减少系统依赖,降低耦合
    • 缺点:
      • 1)当子系统升级或扩展时,可能会给门面角色带来未知的风险(门面角色和子系统耦合)
      • 2)当新增子系统时需要添加到门面角色中(修改门面角色),不符合开闭原则
      • 3)在某些情况下,可能违反单一职责原则
  • 相关阅读:
    Jmeter-线程组下篇
    卷妹带你回顾Java基础(一)每日更新Day10
    2023最新electron 进程间通讯的几种方法
    deepvariant 基因变异识别算法docker版使用
    JavaScript教程-函数绑定,包装器,bind,偏函数,在没有上下文情况下的partial,
    [山东科技大学OJ]1214 Problem B: 编写函数:字符串的连接 之二 (Append Code)
    【C++】构造函数意义 ( 构造函数显式调用与隐式调用 | 构造函数替代方案 - 初始化函数 | 初始化函数缺陷 | 默认构造函数 )
    Shell 脚本面试指南
    SpringBoot 框架 2022-8-1
    技术20期:3种在 Python 中使用 Keras 库评估深度学习模型性能
  • 原文地址:https://blog.csdn.net/Bb15070047748/article/details/126368582