什么是Facade模式
外部和一个系统通信必须通过一个统一的门面(facade)对象进行
facade模式的本质:封装交互,简化调用
很好的提现了最小知识原则
场景
外部系统P要与系统Q的多个模块进行通信,分别是A模块、B模块、C模块等等。这时候对于系统P来说就很麻烦,因为他要熟知系统Q下到底有多少模块以及每个模块具体是干嘛的,复杂度很高。
解决这种不便的方式是在系统Q种引入一个facade对象,主要用于转发。
那么,对于所有外部系统来说,只需要与facade对象交互月底即可,极大的降低了复杂度。
结构
facade例子
新增几个模块对象
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的接口,其他的不需要知道。对于内部系统来说,隐藏了内部的模块细节,松散耦合。
image.png
网友评论