## 什么是Facade模式 外部和一个系统通信必须通过一个统一的门面(facade)对象进行 facade模式的本质:封装交互,简化调用 很好的提现了 ***最小知识原则*** ## 场景 外部系统P要与系统Q的多个模块进行通信,分别是A模块、B模块、C模块等等。这时候对于系统P来说就很麻烦,因为他要熟知系统Q下到底有多少模块以及每个模块具体是干嘛的,复杂度很高。 解决这种不便的方式是在系统Q种引入一个facade对象,主要用于转发。 那么,对于所有外部系统来说,只需要与facade对象交互月底即可,极大的降低了复杂度。 ## 结构 ![](https://img.kancloud.cn/3e/7c/3e7c2ded78b9990387e6521b947164a0_255x273.png) ## 例子 ### 新增几个模块对象 ``` package com.mk.designDemo.designs.facade.module; public class ModuleA { public static void methodA() { System.out.println("invoke method A"); } } package com.mk.designDemo.designs.facade.module; public class ModuleB { public static void methodB() { System.out.println("invoke method B"); } } package com.mk.designDemo.designs.facade.module; public class ModuleC { public static void methodC() { System.out.println("invoke method C"); } } ``` 新增一个config对象 ``` package com.mk.designDemo.designs.facade; import lombok.Data; import lombok.experimental.Builder; @Data @Builder public class FacadeConfig { private boolean config1; private boolean config2; private boolean config3; } ``` 新增一个Facade对象 ``` package com.mk.designDemo.designs.facade; import com.mk.designDemo.designs.facade.module.ModuleA; import com.mk.designDemo.designs.facade.module.ModuleB; import com.mk.designDemo.designs.facade.module.ModuleC; public class SystemFacade { private SystemFacade(){} public static void doSomething(FacadeConfig config) { if(config.isConfig1()){ ModuleA.methodA(); } if(config.isConfig2()){ ModuleB.methodB(); } if(config.isConfig3()){ ModuleC.methodC(); } } } ``` 新增测试类 ``` package com.mk.designDemo.facade; import com.mk.designDemo.designs.facade.FacadeConfig; import com.mk.designDemo.designs.facade.SystemFacade; import com.mk.designDemo.designs.facade.module.ModuleA; import com.mk.designDemo.designs.facade.module.ModuleB; import com.mk.designDemo.designs.facade.module.ModuleC; import org.junit.Test; public class FacadeTest { @Test public void beforeFacade(){ // 外部系统P需要与A、B、C三个模块交互 ModuleA.methodA(); ModuleB.methodB(); ModuleC.methodC(); // 外部系统M需要与A、B三个模块交互 ModuleA.methodA(); ModuleB.methodB(); // 外部系统M需要与B、C三个模块交互 ModuleB.methodB(); ModuleC.methodC(); } @Test public void afterFacade(){ // 外部系统P需要与A、B、C三个模块交互 SystemFacade.doSomething(FacadeConfig.builder().config1(true).config2(true).config3(true).build()); // 外部系统M需要与A、B三个模块交互 SystemFacade.doSomething(FacadeConfig.builder().config1(true).config2(true).build()); // 外部系统M需要与B、C三个模块交互 SystemFacade.doSomething(FacadeConfig.builder().config2(true).config3(true).build()); } } ``` 经过测试,我们发现运行结果完全一致。但是对于外部系统来说,很大程度上降低了他们的学习成本,他们只需要知道有facade的接口,其他的不需要知道。对于内部系统来说,隐藏了内部的模块细节,松散耦合。 ![](https://img.kancloud.cn/94/4d/944dfec15d34e67bccc028e577dc650e_786x427.png)