今天在学习《阿里巴巴java代码开发手册》时见到如下一条规则:
【强制】应用中不可直接使用日志系统(Log4j、Logback)中的 API,而应依赖使用日志框架
SLF4J 中的 API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。 import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger logger = LoggerFactory.getLogger(Abc.class);
其中说到了门面模式,正好利用此机会来聊一聊门面模式
门面模式(Facade)又称外观模式,他隐藏了系统的复杂性,并向客户端提供了一个可以访问系统的接口。
如《阿里巴巴java代码开发手册》中提到的,java体系中现在的日志框架有很多,log4j、Logback都是其中的一种,这些框架在接口的使用上面都会存在一些细微的区别,那我们在具体的使用的过程中是否需要因为项目里使用了log4j,就定制log4j的接口;使用Logback就定制Logback的接口呢?
如果这样的话日志的功能就做的太具体了,正在我们在开发过程中都是只需要通过工厂模式拿到一个logger对象,然后使用logger对象来实现对日志的输出就可以了、具体logger里面的实现是由log4j还是Logback来实现开发者甚至都不需要了解,那使用者当然也不需要了解组件是如何将数据存储,以什么格式输出。
而在系统中需要做的就是配置loggerFactory的实现类,这个一般都是放在系统的配置里了。
来看看门面模式的UML图
图中的Client通过Facade来调用模块ABC的功能,也就屏蔽了与具体模块A/B/C的耦合。
门面模式的使用场景:
1- 为复杂的模块或子系统提供外界访问的模块;
2- 子系统相互独立;
3- 在层析结构中,可以使用外观模式定义系统的每一层的入口。
但是门面模式只适合上述场景,其他场景下有很大的问题:
不能使用门面模式的情况
不符合开闭原则,对修改关闭,对扩展开放。一旦门面对象发生错误,怎么解决?继承?复写?都不顶用,唯一能做的一件事就是修改门面角色的代码,这个风险相当大