场景

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

1.常规

  1. package com.example.demo.pattern.facade;
  2. /**
  3. * @author chenchao
  4. * @date 2021/11/9
  5. */
  6. public class WithoutFacadePatternDemo {
  7. public static void main(String[] args) {
  8. // 假设我们这里是子系统2,要基于子系统1的3个模块的功能实现一个业务逻辑
  9. ModuleA moduleA = new ModuleA();
  10. ModuleB moduleB = new ModuleB();
  11. ModuleC moduleC = new ModuleC();
  12. moduleA.execute();
  13. moduleB.execute();
  14. moduleC.execute();
  15. // 这么搞会有什么问题?
  16. // 问题一:对应子系统1来说,维护成本太高了,就是因为要care多个子系统2的模块。如果只是3个模块还凑合,若果是
  17. // 20个模块呢?那子系统1对子系统2的各个模块的了解就要很多,维护成本很高
  18. // 问题二:就这个多个模块组成的一个功能,如果在子系统1的多个地方都使用到了,那么那段代码就会在多个地方
  19. // 都有重复,复制粘贴的过程,一旦这段业务逻辑修改了,比如还要加入一个模块D的功能,可能就要修改多个地方
  20. // 的代码,会弄的非常的麻烦
  21. }
  22. public static class ModuleA {
  23. public void execute() {
  24. System.out.println("子系统1的模块A的功能");
  25. }
  26. }
  27. public static class ModuleB {
  28. public void execute() {
  29. System.out.println("子系统1的模块B的功能");
  30. }
  31. }
  32. public static class ModuleC {
  33. public void execute() {
  34. System.out.println("子系统1的模块C的功能");
  35. }
  36. }
  37. }

2.外观模式(门面模式)

  1. package com.example.demo.pattern.facade;
  2. /**
  3. * @author chenchao
  4. * @date 2021/11/9
  5. */
  6. public class FacadePatternDemo {
  7. public static void main(String[] args) {
  8. // 假设是子系统2
  9. SystemFacade facade = new SystemFacade();
  10. facade.exucute();
  11. // 好处1:子系统2不需要care太多的模块,只要care一个门面类的接口就可以了
  12. // 好处2:如果多个地方都要调用这段逻辑,那么如果这个逻辑变了,只需要在门面类一个地方修改就可以了
  13. }
  14. /**
  15. * 子系统1的门面类
  16. * @author chenchao
  17. *
  18. */
  19. public static class SystemFacade {
  20. public void exucute() {
  21. // 子系统1,封装了自己的多个模块,ABC,基于自己多个模块的功能,对外统一暴露出去一个功能
  22. ModuleA moduleA = new ModuleA();
  23. ModuleB moduleB = new ModuleB();
  24. ModuleC moduleC = new ModuleC();
  25. moduleA.execute();
  26. moduleB.execute();
  27. moduleC.execute();
  28. System.out.println("新增的一段逻辑");
  29. }
  30. }
  31. public static class ModuleA {
  32. public void execute() {
  33. System.out.println("子系统1的模块A的功能");
  34. }
  35. }
  36. public static class ModuleB {
  37. public void execute() {
  38. System.out.println("子系统1的模块B的功能");
  39. }
  40. }
  41. public static class ModuleC {
  42. public void execute() {
  43. System.out.println("子系统1的模块C的功能");
  44. }
  45. }
  46. }

3.说明

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

就是说,大家可以想象一下,比如说service就是一个经典的门面模式

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