1、简述
外观模式(Facade Pattern)是一种结构型设计模式,通过为多个复杂子系统提供一个一致的接口,使得子系统之间的交互更加简单,降低了客户端和子系统之间的耦合。
设计模式样例:https://gitee.com/lhdxhl/design-pattern-example.git

2、什么是外观模式
外观模式的核心是提供一个高级接口,使得子系统的使用变得简单。通过引入外观类,客户端可以不直接与子系统交互,从而屏蔽了子系统的复杂性。
外观模式的优点:
🔹 降低复杂性:通过引入一个外观类,客户端可以更轻松地与子系统交互。
🔹  松散耦合:客户端和子系统之间的耦合被外观类隔离,方便系统的扩展和维护。
🔹 更好的分层设计:外观类可以作为系统的入口点,帮助我们更清晰地划分层次。
3、实际案例
假设我们有一个家庭影院系统,包括电视、音响和 DVD 播放器。为了看电影,用户需要分别打开这些设备,并设置好输入输出,非常麻烦。我们可以通过外观模式封装这些复杂操作。
// 子系统 1:电视
public class TV {
    public void turnOn() {
        System.out.println("TV is turned on.");
    }
    public void turnOff() {
        System.out.println("TV is turned off.");
    }
}
// 子系统 2:音响
public class SoundSystem {
    public void turnOn() {
        System.out.println("Sound system is turned on.");
    }
    public void setVolume(int level) {
        System.out.println("Sound system volume set to " + level);
    }
    public void turnOff() {
        System.out.println("Sound system is turned off.");
    }
}
// 子系统 3:DVD 播放器
public class DVDPlayer {
    public void turnOn() {
        System.out.println("DVD player is turned on.");
    }
    public void play(String movie) {
        System.out.println("Playing movie: " + movie);
    }
    public void turnOff() {
        System.out.println("DVD player is turned off.");
    }
}
// 外观类
public class HomeTheaterFacade {
    private TV tv;
    private SoundSystem soundSystem;
    private DVDPlayer dvdPlayer;
    public HomeTheaterFacade(TV tv, SoundSystem soundSystem, DVDPlayer dvdPlayer) {
        this.tv = tv;
        this.soundSystem = soundSystem;
        this.dvdPlayer = dvdPlayer;
    }
    public void watchMovie(String movie) {
        System.out.println("Setting up home theater...");
        tv.turnOn();
        soundSystem.turnOn();
        soundSystem.setVolume(20);
        dvdPlayer.turnOn();
        dvdPlayer.play(movie);
        System.out.println("Enjoy your movie!");
    }
    public void endMovie() {
        System.out.println("Shutting down home theater...");
        dvdPlayer.turnOff();
        soundSystem.turnOff();
        tv.turnOff();
    }
}
// 测试代码
public class FacadePatternDemo {
    public static void main(String[] args) {
        TV tv = new TV();
        SoundSystem soundSystem = new SoundSystem();
        DVDPlayer dvdPlayer = new DVDPlayer();
        HomeTheaterFacade homeTheater = new HomeTheaterFacade(tv, soundSystem, dvdPlayer);
        homeTheater.watchMovie("Inception");
        System.out.println();
        homeTheater.endMovie();
    }
}
输出结果
Setting up home theater...
TV is turned on.
Sound system is turned on.
Sound system volume set to 20
DVD player is turned on.
Playing movie: Inception
Enjoy your movie!
Shutting down home theater...
DVD player is turned off.
Sound system is turned off.
TV is turned off.
4、应用场景
🔹 简化复杂子系统的使用:例如,整合多个子系统的接口,提供统一操作入口。
🔹 分层架构:外观模式可以用作系统分层的入口,使得高层模块不直接依赖底层模块,遵循 "迪米特法则"。
🔹 旧系统的重构:通过外观模式,可以封装旧系统的复杂接口,提供更友好的访问方式。
4.1 数据库连接管理
在很多数据库应用中,可以通过外观模式封装连接池的创建、获取和关闭操作:
public class DatabaseConnectionFacade {
    private ConnectionPool connectionPool;
    public DatabaseConnectionFacade(ConnectionPool pool) {
        this.connectionPool = pool;
    }
    public Connection getConnection() {
        return connectionPool.getConnection();
    }
    public void releaseConnection(Connection connection) {
        connectionPool.releaseConnection(connection);
    }
}
4.2. Web 应用开发
在 Spring 框架中,DispatcherServlet 就是一个外观模式的经典例子,它封装了请求的分发、视图解析等功能,对开发者隐藏了内部复杂实现。
4.3 第三方 API 封装
使用外观模式对复杂的第三方 API 进行封装,提供一个简化的接口。例如,对支付系统(支付宝、微信支付等)的统一封装:
public class PaymentFacade {
    private AlipayService alipayService;
    private WechatPayService wechatPayService;
    public PaymentFacade(AlipayService alipayService, WechatPayService wechatPayService) {
        this.alipayService = alipayService;
        this.wechatPayService = wechatPayService;
    }
    public void payWithAlipay(double amount) {
        alipayService.pay(amount);
    }
    public void payWithWechat(double amount) {
        wechatPayService.pay(amount);
    }
}
5、总结
外观模式通过提供一个简化的接口,帮助开发者轻松使用复杂的子系统。它不仅降低了客户端的学习成本,还提高了代码的可维护性。在开发中,通过合理地使用外观模式,可以显著改善系统的设计质量。