门面模式又称外观模式
特点
封装
核心
外部与一个子系统的通信必须通过一个统一的外观对象进行,使得子系统更易于使用。
典型应用场景
【强制】应用中不可直接使用日志系统(Log4j、Logback)中的API,而应依赖使用日志框架
SLF4J中的API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger logger = LoggerFactory.getLogger(Abc.class);
缺点
门面模式最大的缺点就是不符合开闭原则,对修改关闭,对扩展开放,看看我们那个门面对象吧,它可是重中之重,一旦在系统投产后发现有一个小错误,你怎么解决?完全遵从开闭原则,根本没办法解决。继承?覆写?都顶不上用,唯一能做的一件事就是修改门面角色的代码,这个风险相当大,这就需要大家在设计的时候慎之又慎,多思考几遍才会有好收获。
优点
解耦:对于一个设计的全面、完善的日志门面来说,他也应该是天然就兼容了多种日志框架的。所以,底层框架的更换,日志门面几乎不需要改动。
实现
首先要有各个子系统,然后给各个子系统定义个门面,门面里面完成子系统调用,客户端调用子系统的时候,不是直接调用子系统而是通过门面完成子系统的调用,轻松将调用者和子系统之间解耦,管家其实类似SLF4J其实只是一个门面服务而已,他并不是真正的日志框架,真正的日志的输出相关的实现还是要依赖Log4j、logback等日志框架的。
举例
我想吃青椒炒肉,
第一部:命令我的洗菜师,洗菜
第二部:命令我的切菜师,切菜
第三部:命令我的厨师,下锅炒
第四部:命令我的服务员,端到我的面前
如果我一个一个去命令,太麻烦了
所以我找了个管家,帮我去命令(门面)
洗菜师、切菜师、厨师、服务员相当于是子系统
Facade是所有系统的门面,当然每个子系统也可以有门面
FacadeMain调用门面就能完成自己想干的事
public class Washing {
public void washing(String name) {
System.out.println("洗"+name);
}
}
public class CutUp {
public void cutUp(String name) {
System.out.println("切"+name);
}
}
public class Stir {
public void stir(String name) {
System.out.println("炒"+name);
}
}
public class ServingDishes {
public void servingDishes(String name) {
System.out.println("端"+name);
}
}
/**
* 我的管家提供的了一个炒菜的方法
*/
public class Facade {
private Washing washing = new Washing();
private CutUp cutUp = new CutUp();
private Stir stir = new Stir();
private ServingDishes servingDishes = new ServingDishes();
/**
* 点菜
* @param name 菜名
*/
public void order(String name){
washing.washing(name);
cutUp.cutUp(name);
stir.stir(name);
servingDishes.servingDishes(name);
}
}
public class FacadeMain {
public static void main(String[] args) {
Facade facade = new Facade();
facade.order("青椒炒肉");
}
}