My logo
Published on

facade 外观(门面)模式

外观(门面)模式,比如我们有一个系统A吧,自己内部有多个代码组件,每个代码组件都可以实现一些功能。此时如果别的系统B要调用系统A实现某个功能,此时一种方法是,系统B调用系统A的多个代码组件的方法,最终实现一个功能。另外一个选择,就是系统A里提供一个Facade类,系统B不需要知道系统A内部有多少个代码组件,直接调用系统A的一个facade类的一个方法即可。

比如说service就是一个经典的门面模式。

如果一个子系统里有多个DAO组件,然后如果别的子系统要实现一段业务逻辑,需要使用这个子系统的多个DAO组件,那就会导致别的子系统代码会很乱,需要知道这个子系统很多DAO组件的实现。但是这个组件可以基于多个DAO组件封装出来一个service接口,然后别的系统就针对一个service接口开发即可。

场景

  1. 假设我们现在有两个子系统
  2. 子系统A,有多个内部模块,模块A、模块B和模块C
  3. 子系统B,现在有一个功能,需要同时依赖3个模块来实现一个功能

一般模式编写:

package wang.jinggo.basics.zhss.facade;

/**
 * @author: wangyj
 * @create: 2021-10-20
 * @version: 1.0.0
 **/
public class WithoutFacadePatternDemo {

    public static class ModuleA {

        public void execute() {
            System.out.println("子系统1的模块A的功能");
        }

    }

    public static class ModuleB {

        public void execute() {
            System.out.println("子系统1的模块B的功能");
        }

    }

    public static class ModuleC {

        public void execute() {
            System.out.println("子系统1的模块C的功能");
        }

    }

    public static void main(String[] args) {
        // 假设我们这里是子系统2,要基于子系统1的3个模块的功能实现一个业务逻辑
        ModuleA moduleA = new ModuleA();
        ModuleB moduleB = new ModuleB();
        ModuleC moduleC = new ModuleC();

        moduleA.execute();
        moduleB.execute();
        moduleC.execute();

        // 问题一:对应子系统1来说,维护成本太高了,就是因为要care多个子系统2的模块。如果只是3个模块还凑合,若果是
        // 20个模块呢?那子系统1对子系统2的各个模块的了解就要很多,维护成本很高

        // 问题二:就这个多个模块组成的一个功能,如果在子系统1的多个地方都使用到了,那么那段代码就会在多个地方
        // 都有重复,复制粘贴的过程,一旦这段业务逻辑修改了,比如还要加入一个模块D的功能,可能就要修改多个地方
        // 的代码,会弄的非常的麻烦
    }
}

设计模式编写:

package wang.jinggo.basics.zhss.facade;

/**
 * @author: wangyj
 * @create: 2021-10-20
 * @version: 1.0.0
 **/
public class FacadePatternDemo {

    public static void main(String[] args) {
        // 假设是子系统2
        SystemFacade facade = new SystemFacade();
        facade.exucute();

        // 好处1:子系统2不需要care太多的模块,只要关注一个门面类的接口就可以了
        // 好处2:如果多个地方都要调用这段逻辑,那么如果这个逻辑变了,只需要在门面类一个地方修改就可以了
    }

    /**
     * 子系统1的门面类
     *
     */
    public static class SystemFacade {

        public void exucute() {
            // 子系统1,封装了自己的多个模块,ABC,基于自己多个模块的功能,对外统一暴露出去一个功能
            ModuleA moduleA = new ModuleA();
            ModuleB moduleB = new ModuleB();
            ModuleC moduleC = new ModuleC();

            moduleA.execute();
            moduleB.execute();
            moduleC.execute();
            System.out.println("新增的一段逻辑");
        }

    }

    public static class ModuleA {

        public void execute() {
            System.out.println("子系统1的模块A的功能");
        }

    }

    public static class ModuleB {

        public void execute() {
            System.out.println("子系统1的模块B的功能");
        }

    }

    public static class ModuleC {

        public void execute() {
            System.out.println("子系统1的模块C的功能");
        }

    }
}