外观模式(Facade Pattern)
概念
外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性。他类似于在多个系统中做一个中间者的模式,封装一个复杂的逻辑给调用方使用;
简介
作用及优势
- 将复杂的接口封装起来,对外提供简单的入口
- 减少了系统之间的耦合性
- 提高了系统的安全性
不足之处
如果要改东西很麻烦,继承重写都不合适。可以理解为都是一些固有的东西,只是封装起来了;不适合去扩展,只能通过新api来暴露;
场景
- 认证模块提供给业务模块的登录接口
- mvc三层架构也用了这种思想
代码
案例描述
相当于有两个系统A、B;这两个系统都需要使用支付,但是支付系统C想调用很复杂,于是乎又来了第三个系统D(支付sdk);此时A、B只需要引入C系统的sdk即可选择支付方式;之后想增加支付方式,继续往系统D中添加即可;
工程目录
项目类图
具体实现
支付接口(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 ===
=== 支付完成 ===