这是我参与2022首次更文挑战的第11天,活动详情查看:2022首次更文挑战
门面模式
概述
在日常生活中们我们都或多或少的使用过门面模式,比如在政府网站,可以通过这一个政府网站可以访问到其他的相关的子网站,比如税务局、电力局、劳动局等,不仅仅在我们在生活中使用了很多门面模式,包括我们在代码中也使用了很多门面模式,凡是高层模块需要调用多个子系统,都会使用到门面模式,把调用这些子系统的接口都封装到一个接口类中,从而使高层系统直接或者间接的访问这些子系统的功能。那么什么时候门面模式?
门面模式(Facade Pattern)又被称为外观模式,是提供一个统一的接口,通过这个接口去访问多个子系统的多个不同的接口,它为子系统中的一组接口提供一个统一的高层接口。使得子系统更容易使用。在类的创建过程中,属于结构型模式。
门面模式的应用场景
-
生活中的医院看病,可以挂号、缴费等都是不同系统的交互
-
java的三层架构模式
-
分布式的Gateway网关功能
-
Tomcat的RequestFacade类
门面模式的通用写法
门面模式基本是有两类角色
-
门面(Facade)角色 : 用户可以调用这个角色类的方法。这个类知晓相关的(一个或者多个)子系统的功能和责任。在正常情况下,本类会将所有从客户端发来的请求委派到相应的子系统去。
-
子系统(SubSystem)角色 : 可以同时有一个或者多个子系统。每个子系统都不是一个单独的类,而是一个类的集合(如上面的子系统就是由ModuleA、ModuleB、ModuleC三个类组合而成)。每个子系统都可以被客户端直接调用,或者被门面角色调用。子系统并不知道门面的存在,对于子系统而言,门面仅仅是另外一个客户端而已。
下面是门面模式的通用写下,首先分别创建三个子系统Edu、Police、Social类,然后创建一个门面类ReceptionCenter,里面整合了三个接口的方法。
- ReceptionCenter门面角色
public class ReceptionCenter {
Edu edu = new Edu();
Police police = new Police();
Social social = new Social();
public void handleTest(String name) {
edu.school(name);
police.register(name);
social.handleSocial(name);
}
}
- Edu子系统
public class Edu {
public void school(String name){
System.out.println(name+"学校完毕");
}
}
- Police子系统
public class Police {
public void register(String name){
System.out.println(name+"已办理完毕");
}
}
- Social子系统
public class Social {
public void handleSocial(String name){
System.out.println(name+"转移完成");
}
}
ReceptionCenter类其实相当于Edu、Police、Social模块的外观界面,有了这个ReceptionCenter类,那么客户端就不需要亲自调用子系统中的Edu、Police、Social模块了,也不需要知道系统内部的实现细节,甚至都不需要知道Edu、Police、Social模块的存在,客户端只需要跟ReceptionCenter类交互就好了,从而更好地实现了客户端和子系统中Edu、Police、Social模块的解耦,让客户端更容易地使用系统。
门面模式的优缺点
优点
-
简单易用: 门面模式让子系统更加易用,简化了对各个子系统的调用过程,客户端不再需要了解子系统内部的实现,也不需要跟众多子系统内部的模块进行交互,只需要跟门面类交互就可以了。
-
松散耦合: 门面模式松散了客户端与子系统的耦合关系,让子系统内部的模块能更容易扩展和维护。
-
更好的划分访问层次: 通过合理使用Facade,可以帮助我们更好地划分访问的层次。有些方法是对系统外的,有些方法是系统内部使用的。把需要暴露给外部的功能集中到门面中,这样既方便客户端使用,也很好地隐藏了内部的细节。
-
遵循迪米特法则,最少知道原则
缺点
-
当增加子系统或者扩展系统行为时,可能会带来未知的风险
-
不符合开闭原则,即对添加开放,对修改关闭
-
在某些情况下违背了单一职责原则,即一个类应该只负责一个功能。
门面模式与代理模式的区别
-
门面模式是一种特殊的静态代理模式
-
门面模式重点是在于封装,静态代理模式重点在于增强(不增强的静态代理就是门面模式)