Java设计模式-门面模式(Facade Pattern)
目录
- 什么是门面模式
- 门面的实现方式
- JavaSE门面模式的应用
- Struts2门面模式的应用
门面模式提供了内部子系统的访问接口,只简单的转发,不做业务处理
一、什么是门面模式
门面模式(Facade Pattern):外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
门面模式有点像防火墙NAT端口转发,想访问我的内部系统,得先通过防火墙开端口,外网端口映射到内网端口,只是转发而已不做任何处理。
门面模式还有个作用是减少对象之间的耦合关系,如果外部系统在请求内部系统时可以访问内部系统的任意子系统,那么耦合关系将变得非常复杂,封装一个门面类,门面类负责将请求转发到子系统,是不是有点像命令模式?无论你点什么菜,都要经过服务员(请求者(Invoker)角色),服务员负责通知厨师。他们的区别我们后面再总结
二、门面模式的实现方式
举个去医院看病的例子,一般都需要先看医生、化验、复诊、结算,很多老人没有办法自己做完所有的流程,但子女都忙,所以医院有了陪诊员的角色,它会帮我们接触所有医院各个部门的人
下半部分是使用门面模式之后的UML图,实现代码如下
package org.Facade.version1;
class Register{
public void register(){
System.out.println("挂号......");
}
}
class Doctor{
public void talk(){
System.out.println("医生看病......");
}
}
class Nurse{
public void drawBlood(){
System.out.println("护士抽血......");
}
}
class Cashier{
public void pay(){
System.out.println("缴费......");
}
}
class Servicer{
private Register register = new Register();
private Doctor doctor = new Doctor();
private Nurse nurse = new Nurse();
private Cashier cashier = new Cashier();
public Servicer(){
System.out.println("陪诊员负责完成所有看病业务");
}
private void register(){
register.register();
}
private void talk(){
doctor.talk();
}
private void drawBlood(){
nurse.drawBlood();
}
private void pay(){
cashier.pay();
}
public void service(){
this.register();
this.talk();
this.drawBlood();
this.pay();
}
}
public class TestFacade {
public static void main(String[] args) {
Servicer servicer = new Servicer();
servicer.service();
}
}
// 运行结果
陪诊员负责完成所有看病业务
挂号......
医生看病......
护士抽血......
缴费......
门面模式除了暴露的service是public其它的都是private,保证了只暴露一个统一接口,是不是非常简单
门面模式和命令模式的不同
- 门面模式是结构型模型,命令模式是行为型模型
- 门面模式关注的是如何封装实现结构,命令模式关注方法间的通信解耦
- 门面关注的是整体操作,命令模式关注的是内部细节操作,例如命令模式可以撤回
- 门面模式不符合开闭原则(需要修改门面),命令模式符合(只需要增加命令类)
门面模式和命令模式的相同之处
- 都是实现客户端与最终执行者的解耦
- 逐渐增加系统复杂性,门面模式的门面类会不断庞大复杂;命令模式的命令类会逐渐增加;
门面模式的缺点
- 不符合开闭原则,新增接口需要修改门面类
三、JavaSE门面模式的应用
3.1 java.lang.Class是门面模式
该类对外提供了JDK底层操作JVM的方法,Class类就是门面类
3.2 slf4j典型的门面模式
随着日志的的发展,目前用的较多有JDK自带的jul,log4j(已逐步淘汰)、log4j2、logback等。较大的系统,会拆分为各个微服务,最后再进行互相调用,如果各个微服务项目经理之间未达成共识,可能每个服务用的日志还不一样,比如有的小组用的jul,有的小组用的log4j,这样给后期维护运维就带来了一些难题
因此我们在使用日志的时候需要去加一层日志门面也就是slf4j,slf4j和具体日志对接的时候,需要配置桥接器,就可以使用了,各个日志插件的桥接器如下:
如果项目合并使用的时候,因为多日志就会有些影响了,这样就不得不修改其中一端,造成了一些不必要的工作量,在阿里开发规范中,就有这样一条: 强制:应用中不可直接使用日志系统(log4j、logback)中的 API ,而应依赖使用日志框架 SLF4J 中的 API 。使用门面模式的日志框架,有利于维护和各个类的日志处理方式的统一。
四、Struts2门面模式的应用
暂未发现,如果读者有发现,请联系我添加,谢谢