携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第16天,点击查看活动详情
简介
外观模式的定义:
外观模式提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。使用外观模式时,我们创建了一个统一的类,用来包装子系统中一个或多个复杂的类,客户端可以直接通过外观类来调用内部子系统中方法,从而外观模式让客户和子系统之间避免了紧耦合。
外观模式也被叫做门面模式,通俗理解起来就是提供一个门面给外部进行调用,将内部细节统一在一个方法里面。跟一个外交官一样,由统一的人员与外部人员打交道,隐藏内部的复杂性。
这种模式涉及到一个单一的类,该类提供了客户端请求的简化方法和对现有系统类方法的委托调用。
案例
我们通过我们熟知的事务来举例:要把一只大象放进冰箱需要几步
首先,我们打开冰箱的门:
public class OpenFridge {
private String user;
public OpenFridge(String user) {
this.user = user;
}
public void open() {
System.out.println(user + "open");
}
}
然后把大象放进去
public class PutElephant {
public void putIn(){
System.out.println("put elephant in");
}
}
然后把冰箱门关上
public class CloseFridge {
private String user;
public CloseFridge(String user) {
this.user = user;
}
public void close() {
System.out.println(user + "close");
}
}
那我们如果用传统的方式来完成这个过程,则需要实例化这三个类,然后分别按顺序进行调用。
public class App {
public static void main(String[] args) {
OpenFridge openF = new OpenFridge("张三");
PutElephant putElephant = new PutElephant();
CloseFridge closeF = new CloseFridge("张三");
openF.open();
putElephant.putIn();
closeF.close();
}
}
如果这样调用我们要控制好调用的逻辑顺序,要知道各个类各个方法分别是什么含义。但是我作为客户端,我不想知道你内部的实现逻辑是怎样的,内部的依赖是怎样的,我并不关心,客户端只需要提供一个门面方法,一个高层的接口给我调用,完成功能即可。
即我们需要提供一个门面类
public class Fascade {
private OpenFridge openFridge;
private PutElephant putElephant;
private CloseFridge closeFridge;
public Fascade(String user) {
this.openFridge = new OpenFridge(user);
this.putElephant = new PutElephant();
this.closeFridge = new CloseFridge(user);
}
public void openPutClose() {
openFridge.open();
putElephant.putIn();
closeFridge.close();
}
}
这个时候我们的客户端类调用起来就简单清晰多了
public class App {
public static void main(String[] args) {
Fascade lisi = new Fascade("李四");
lisi.openPutClose();
}
}
这样看来,门面模式也有点类似做了一层封装的工作。
总结
外观模式的有点很明显,它降低了客户端与子系统类的耦合度,实现了子系统与客户之间的松耦合关系。而且外观类对子系统的接口封装,使得系统更易于使用。提高灵活性,不管子系统如何变化,只要不影响门面对象,就可以自由修改。但是它同样也有不好的一面,首先它违背了【开闭原则】,如果后续子系统的逻辑顺序要变化,那就要去修改这个门面类了。