一. 概述
1. 什么是外观模式
外观模式(Facade)也叫做门面模式,他隐藏了系统的复杂性,并向客户端提供了一个可以访问系统的接口。这种类型的设计模式属于结构性模式。为子系统中的一组接口提供了一个统一的访问接口,这个接口使得子系统更容易被访问或者使用。堪称最简单的设计模式之一!
2. 外观模式应用场景
简单来说,该模式就是把一些复杂的流程封装成一个接口供给外部用户更简单的使用。这个模式中,设计到3个角色。
① 门面角色:外观模式的核心。它被客户角色调用,它熟悉子系统的功能。内部根据客户角色的需求预定了几种功能的组合。
② 子系统角色:实现了子系统的功能。它对客户角色和Facade时未知的。它内部可以有系统内的相互交互,也可以由供外界调用的接口。
③ 客户角色:通过调用Facede来完成要实现的功能。
二. 实际案例
拿之前的支付回调代码为例,实际的异步通知一般有如下四步,下图是伪代码,实际代码多则100多行,可读性非常差!
此时,我们可以用外观模式进行重构:
1. 首先,可以把这四步看做四个模块
① 日志收集
@Component
@Slf4j
public class LogService {
public void logService(Map<String, String> verifySignature) {
// 1.第一步打印日志信息
String orderId = verifySignature.get("orderId"); // 获取后台通知的数据,其他字段也可用类似方式获取
String respCode = verifySignature.get("respCode");
log.info("第一个模块>>>orderId:{},respCode:{}", orderId, respCode);
}
}
② 修改订单状态
@Slf4j
@Component
public class PaymentService {
@Autowired
private OrderDao orderDao;
public void updatePaymentStatus(Map<String, String> verifySignature) {
// 第二步 修改状态为已支付
orderDao.updateStatus(verifySignature.get("orderId"));
}
}
③ 调用积分服务接口
@Component
public class IntegralService {
public void callIntegral(Map<String, String> verifySignature) {
// 3.调用积分接口增加积分
String orderId = verifySignature.get("orderId");
IntegralFeign.addScore(orderId;
}
}
④ 调用消息服务平台
@Component
@Slf4j
public class MsgService {
public void sendMessage(Map<String, String> verifySignature) {
log.info("第四个模块>>>发消息>>>>>");
String orderId = verifySignature.get("orderId");
// 根据订单id获取购买人手机号,发送消息通知
}
}
2. 构建门面(外观)角色
@Component
public class PayCallbackFacade {
@Autowired
private LogService logService;
@Autowired
private PaymentService paymentService;
@Autowired
private IntegralService integralService;
@Autowired
private MsgService msgService;
public boolean callbackFacade(Map<String, String> verifySignature) {
// 1.日志收集
logService.logService(verifySignature);
// 2.修改订单状态
paymentService.updatePaymentStatus(verifySignature);
// 3.调用积分服务接口
integralService.callIntegral(verifySignature);
// 4.调用消息服务平台
msgService.sendMessage(verifySignature);
return true;
}
}
此时,在需要支付回调的业务方法中直接调用门面即可:
编写接口进行测试,会依次执行上述四个步骤:
三. 小结
1. 外观模式优点:
① 松散耦合:使得客户端和子系统之间解耦,让子系统内部的模块功能更容易扩展和维护
② 简单易用:客户端根本不需要知道子系统内部的实现,或者根本不需要知道子系统内部的构成,它只需跟Facade类交互即可
2. 外观模式缺点:
业务封装类会随着后期业务的扩展而增加
但归根结底,优点肯定大于缺点,学会这一设计模式,可以很大程度上提高我们代码的可观赏性!快去重构你的代码吧 ~