外观模式(Facade Pattern)

概念

外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性。他类似于在多个系统中做一个中间者的模式,封装一个复杂的逻辑给调用方使用;

简介

作用及优势

  • 将复杂的接口封装起来,对外提供简单的入口
  • 减少了系统之间的耦合性
  • 提高了系统的安全性

不足之处

如果要改东西很麻烦,继承重写都不合适。可以理解为都是一些固有的东西,只是封装起来了;不适合去扩展,只能通过新api来暴露;

场景

  • 认证模块提供给业务模块的登录接口
  • mvc三层架构也用了这种思想

代码

案例描述

相当于有两个系统A、B;这两个系统都需要使用支付,但是支付系统C想调用很复杂,于是乎又来了第三个系统D(支付sdk);此时A、B只需要引入C系统的sdk即可选择支付方式;之后想增加支付方式,继续往系统D中添加即可;

工程目录

外观模式.jpg

项目类图

外观模式_1.jpg

具体实现

支付接口(Pay)

/**
 * 功能描述: 支付
 *
 * @author: WuChengXing
 * @create: 2021-07-10 00:33
 **/
public interface Pay {
    void aliPay();
    void wxPay();
}

公共实现(CommonPay):

/**
 * 功能描述:
 *
 * @author: WuChengXing
 * @create: 2021-07-10 00:34
 **/
public abstract class CommonPay implements Pay {
    @Override
    public void aliPay() {

    }

    @Override
    public void wxPay() {

    }
}

两个具体的子实现:支付宝AliPay、微信WxPay


/**
 * 功能描述: 支付宝付款
 *
 * @author: WuChengXing
 * @create: 2021-07-10 00:36
 **/
public class AliPay extends CommonPay {
    @Override
    public void aliPay() {
        System.out.println("=== 组装各类配置:公钥、私钥 ===");
        System.out.println("=== 开始调用支付宝SDK ===");
        System.out.println("=== 支付完成 ===");
    }
}

------------------------------------------------

/**
 * 功能描述: 微信支付
 *
 * @author: WuChengXing
 * @create: 2021-07-10 00:38
 **/
public class WxPay extends CommonPay {
    @Override
    public void wxPay() {
        System.out.println("=== 组装各类配置:appid、appkey ===");
        System.out.println("=== 开始调用微信SDK ===");
        System.out.println("=== 支付完成 ===");
    }
}

对外的sdk(PaySdk):

/**
 * 功能描述: 支付SDK
 *
 * @author: WuChengXing
 * @create: 2021-07-10 00:39
 **/
public class PaySdk {
    private Pay aliPay;
    private Pay wxPay;

    public PaySdk() {
        this.aliPay = new AliPay();
        this.wxPay = new WxPay();
    }

    /**
     * 支付宝支付
     */
    public void aliPay(){
        aliPay.aliPay();
    }

    /**
     * 微信支付
     */
    public void wxPay(){
        wxPay.wxPay();
    }
}

这里可以理解为将支付方式的底层封装完毕,现在提供api给其他系统使用即可;

订单系统(OrderSystem):

/**
 * 功能描述: 订单系统
 *
 * @author: WuChengXing
 * @create: 2021-07-10 00:44
 **/
public class OrderSystem {

    PaySdk paySdk;

    public OrderSystem(PaySdk paySdk) {
        this.paySdk = paySdk;
    }

    public void placeOrderAliPay(){
        System.out.println("=== 下单 ===");
        System.out.println("=== 下单成功,使用支付宝支付 ===");
        paySdk.aliPay();
    }

    public void placeOrderWxPay(){
        System.out.println("=== 下单 ===");
        System.out.println("=== 下单成功,使用微信支付 ===");
        paySdk.wxPay();
    }
}

这里初始化SDK后,然后调用支付功能就行,不需要其他额外的操作,当然这里其实可以在想pay方法里面传入订单id的,这样会更符合现实逻辑;

测试

/**
 * 功能描述: 外观模式测试
 *
 * @author: WuChengXing
 * @create: 2021-07-10 00:32
 **/
public class ExteriorTest {
    public static void main(String[] args) {
        OrderSystem orderSystem = new OrderSystem(new PaySdk());
        System.out.println("----------- shopping -----------");
        orderSystem.placeOrderAliPay();
        System.out.println("----------- shopping -----------");
        orderSystem.placeOrderWxPay();
    }
}

结果:

----------- shopping -----------
=== 下单 ===
=== 下单成功,使用支付宝支付 ===
=== 组装各类配置:公钥、私钥 ===
=== 开始调用支付宝SDK ===
=== 支付完成 ===
----------- shopping -----------
=== 下单 ===
=== 下单成功,使用微信支付 ===
=== 组装各类配置:appid、appkey ===
=== 开始调用微信SDK ===
=== 支付完成 ===