初识设计模式 - 外观模式

时间:2022-10-09 09:09:14

简介

外观设计模式(Facade Design Pattern)又被叫作门面模式,其描述是,通过为多个复杂的子系统提供统一的接口,使得子系统更容易被使用。

在现实生活中,常常存在办事复杂的情况,如办理房产证或者注册公司,有时需要跑几个部门才能办成,如果这些部门都在一个地方,或者是成立一个综合部门就方便很多。

对于上述例子,成立综合部分就相当于使用外观模式,为客户端提供统一的接口,从而降低的系统的耦合度、降低客户端的使用难度。

具体实现

创建一个抽象的图形接口,定义一个画图的行为:

public interface Shape {
    void draw();
}

实现一个画圆形的具体类:

public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("在这里画圆形!");
    }
}

定义一个画正方形的具体类:

public class Square implements Shape {
    @Override
    public void draw() {
        System.out.println("在这里画正方形!");
    }
}

随着具体类越来越多,客户端调用这些类也变得更多,则耦合度变得越来越高。这时就可以通过外观模式将这些具体类汇总到同一个接口中,客户端只需掌握这个外观类即可。

定义一个图形类的外观类,将具体类都注入到其中:

public class ShapeFacade {
    private final Shape circle = new Circle();  
    private final Shape square = new Square();

    public void drawCircle() {
        circle.draw();
    }

    public void drawSquare() {
        square.draw();
    }
}

总结

优点

外观模式的主要优点如下:

  • 降低了子系统与客户端的耦合度,使得子系统的变化不会影响调用它的客户端
  • 对客户端屏蔽了子系统组件,减少了客户处理的对象数目,使得子系统使用起来更加简便
  • 只是提供了一个访问子系统的统一入口,并不影响客户端直接使用子系统类

缺点

外观模式的主要缺点如下:

  • 不能很好地限制客户端使用子系统类,很容易带来未知风险
  • 增加新的子系统类可能需要修改外观类或者客户端的代码,违背了开闭原则

适用场景

外观模式的适用场景如下:

  • 解决易用性问题,当需要访问一系列复杂的子系统时,外观模式可以为客户端提供简单的入口
  • 解决性能问题,调用多个接口改成调用一个统一接口,可以减少网络通信成本
  • 解决分布式事务问题,对于不同模块还需要保持事务性,则可以设计一个包括两个操作的新接口在同一个事务里执行

源码

外观模式是一种使用频率非常高的设计模式,如 JDK 中的 java.util.logging.LogManager 简单地使用了外观模式,其中统一了 SystemLoggerContextLoggerContext 这两个内部类。