设计模式之外观模式

90 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 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();
    }
}

这样看来,门面模式也有点类似做了一层封装的工作。

总结

外观模式的有点很明显,它降低了客户端与子系统类的耦合度,实现了子系统与客户之间的松耦合关系。而且外观类对子系统的接口封装,使得系统更易于使用。提高灵活性,不管子系统如何变化,只要不影响门面对象,就可以自由修改。但是它同样也有不好的一面,首先它违背了【开闭原则】,如果后续子系统的逻辑顺序要变化,那就要去修改这个门面类了。