1.定义
外观模式,又叫门面模式,是结构型模式的一种,目的是为多个复杂的子系统提供一个统一的访问接口(门面),使得客户端访问这些子系统的门槛降低,并且具有统一的访问规范。对于客户端来说,极大的屏蔽了子系统的复杂性,客户端只需要面向自身需要的或者是对自己有用的接口即可。
外观模式是所有设计模式中相对比较容易理解的模式,尽管你可能不知道它,但是平时编码中,可能会不经意间就使用到了这种设计模式。说的通俗点就是面对一个或多个庞大的业务子系统,我们只用到了其中部分资源,我们没有必要去直接调用子系统的接口,核心思想就是客户端不应该去直接面对一个复杂庞大且功能冗余的系统,这相当于增加了客户端的复杂性。
于是就可以对客户端真正需要的功能单独抽象出一个中间层供客户端使用,也就是一个“门面”,很形象的比喻。
通过这个“门面”,向客户端屏蔽了子系统的复杂性,简化使用,只面对自己需要的,客户端无需关心和维护复杂的子系统,降低了子系统和客户端的耦合度,子系统发生变化,也不会直接影响到客户端,但是子系统只和“门面”是耦合的,如果子系统发生改变,门面类(外观类)可能需要改变。
举个栗子:汽车动力系统非常复杂,但是没人愿意换挡的时候去手掰变速齿轮,取而代之的是一套变速箱提供给司机使用,司机也不需要知道齿轮之间是怎么切换怎么结合的。
具体角色:
- 外观角色(Facade):为多个子系统提供统一封装
- 子系统角色(SubSystem):客户端调用的功能对象
2.示例
具体实现就是通过创建一个外观类(门面类),单独封装客户端需要的功能和流程,客户端需要的时候直接调用外观类,即客户端面向外观
给出一个简单实现,分别实现三个子系统
/**
* @description: 子系统1
* @version: 1.0
*/
public class SubSystem1 {
public void func1(){
System.out.println("子系统1 ===> 功能1");
}
public void func2(){
System.out.println("子系统1 ===> 功能2");
}
}
/**
* @description: 子系统2
* @version: 1.0
*/
public class SubSystem2 {
public void func1(){
System.out.println("子系统2 ===> 功能1");
}
public void func2(){
System.out.println("子系统2 ===> 功能2");
}
}
/**
* @description: 子系统3
* @version: 1.0
*/
public class SubSystem3 {
public void func1(){
System.out.println("子系统3 ===> 功能1");
}
public void func2(){
System.out.println("子系统3 ===> 功能2");
}
}
定义一个外观类,外观类中持有子系统的对象,面向客户端需要的功能或流程,单独将子系统功能封装到方法中,供客户端使用
/**
* @description: 外观类
* @version: 1.0
*/
public class Facade {
private SubSystem1 sys1 = new SubSystem1();
private SubSystem2 sys2 = new SubSystem2();
private SubSystem3 sys3 = new SubSystem3();
public void process1(){
sys1.func1();
sys3.func2();
}
public void process2(){
sys3.func2();
sys2.func1();
}
}
测试
/**
* @description: test
* @version: 1.0
*/
public class Test {
public static void main(String[] args) {
Facade facade = new Facade();
facade.process1();
facade.process2();
}
}
input:
子系统1 ===> 功能1
子系统3 ===> 功能2
子系统3 ===> 功能2
子系统2 ===> 功能1
3.总结
外观模式整体表现就是在客户端和子系统之间增加一层中间层,分离客户端和子系统,通过中间层屏蔽子系统的复杂性,向客户端提供简单透明的操作入口。当客户端和多个子系统之间存在很大关系时,可以考虑使用外观模式,将客户端和子系统调用分割,提高系统独立性,降低和子系统之间的耦合性。