1. 设计模式之外观模式:将多个内部模块调用封装在一个类中
1.1. 介绍
外观模式(Facade Pattern)是一种 结构型设计模式,它提供了一个 统一的接口,用于访问子系统中的一组接口,从而 简化客户端与复杂子系统之间的交互。
例如,项目开发中,Service 层就是经典的外观模式,系统中有各种 DAO 组件,别的系统调用需要该子系统各种 DAO 组件配合来满足,如果直接暴露 DAO 组件来满足其他系统调用,会增加调用的复杂性、耦合性,还要关系其他系统逻辑。
Service会把自己系统的 DAO 组件封装成一个个方法,供外部调用,这样其他系统不需要关注其他系统的逻辑了,当暴露的接口有 100个地方调用,需要调整接口逻辑时,只需要子系统自己调整,所有调用方都不需要改动。
优缺点及建议
优点
1.简化客户端调用:客户端只需调用外观类的方法,无需关心子系统细节。
2.降低耦合度:子系统变化不会影响客户端代码。
3.提高可维护性:子系统逻辑可以独立修改,不影响外观类。
缺点
1.可能违反开闭原则:如果子系统新增功能,可能需要修改外观类。
2.外观类可能变得臃肿:如果子系统过于复杂,外观类可能会包含大量逻辑。
1.2. 实现及相关代码
假设有两个系统,系统2 调用 系统1的功能。
1.2.1. 没使用设计模式方式
接口及数据对象
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的功能,可能就要修改多个地方的代码,不利于调整维护。
1.2.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的功能");
}
}
调用方法
public static void main(String[] args) {
// 假设是子系统2
// 好处1:子系统2不需要care太多的模块,只要care一个门面类的接口就可以了
// 好处2:如果多个地方都要调用这段逻辑,那么如果这个逻辑变了,只需要在门面类一个地方修改就可以了
SystemFacade facade = new SystemFacade();
facade.exucute();
}
1.3. 总结
外观模式通过 封装复杂子系统,提供 简洁的接口,使客户端更容易使用系统。它适用于 需要简化复杂交互 的场景,是 降低系统耦合度 的有效手段。