1、什么是外观模式
    将一些复杂的流程封装成一个接口对外提供,同时对这个有复杂逻辑的接口进行优化,一般都是按照功能来分割开来,但是这样会使代码更容易浏览,逻辑更为清晰,调试更为简单。

    2、外观模式的应用场景

    图片1.png
    刚刚上边也提到了,外观模式就是将复杂的流程封装为一个接口给用户调用,该模式有三种角色:
    子系统角色:将复杂的流程按照功能分割成各个模块,每个模块就称之为子系统角
    色。
    门面角色:外观模式的核心,调用子系统角色,将各个子系统角色组合起来。
    客户角色:通过调用Facade来完成要实现的功能。

    3、具体代码实现

    需要重构的代码

    1. @Slf4j
    2. public class PayCallbackService {
    3. // 用户下单成功后,有那些操作?
    4. // 1.增加支付回调接口日志
    5. // 2.修改订单数据库状态为已经成功
    6. // 3.调用积分服务接口
    7. // 4.调用消息服务平台服务接口
    8. public boolean callback(Map<String, String> verifySignature) {
    9. // 1.第一步打印日志信息
    10. String orderId = verifySignature.get("orderId"); // 获取后台通知的数据,其他字段也可用类似方式获取
    11. String respCode = verifySignature.get("respCode");
    12. log.info("orderId:{},respCode:{}", orderId, respCode);
    13. // 2.修改订单状态为已经支付
    14. new PaymentTransactionMapper() {
    15. @Override
    16. public void updatePaymentStatus() {
    17. log.info(">>>修改订单状态为已经支付>>>>>");
    18. }
    19. }.updatePaymentStatus();
    20. // 3.调用积分接口增加积分
    21. HttpClientUtils.doPost("jifen.com", "积分接口");
    22. // 4.调用消息服务平台提示
    23. HttpClientUtils.doPost("msg.com", "调用消息接口");
    24. return true;
    25. }
    26. }

    优化后

    1. //创建各个子系统角色想·
    2. @Component
    3. @Slf4j
    4. public class LogService {
    5. public void logService(Map<String, String> verifySignature) {
    6. // 1.第一步打印日志信息
    7. String orderId = verifySignature.get("orderId"); // 获取后台通知的数据,其他字段也可用类似方式获取
    8. String respCode = verifySignature.get("respCode");
    9. log.info("第一个模块>>>orderId:{},respCode:{}", orderId, respCode);
    10. }
    11. }
    12. @Slf4j
    13. @Component
    14. public class PaymentService {
    15. public void updatePaymentStatus() {
    16. // 2.修改订单状态为已经支付
    17. new PaymentTransactionMapper() {
    18. @Override
    19. public void updatePaymentStatus() {
    20. log.info("第二个模块>>>修改订单状态为已经支付>>>>>");
    21. }
    22. }.updatePaymentStatus();
    23. }
    24. }
    25. @Component
    26. @Slf4j
    27. public class IntegralService {
    28. public void callIntegral() {
    29. // 3.调用积分接口增加积分
    30. HttpClientUtils.doPost("jifen.com", "积分接口");
    31. log.info("第三个模块>>>调用积分接口打印日志>>>>>");
    32. }
    33. }
    34. @Component
    35. @Slf4j
    36. public class MsgService {
    37. public void msgService() {
    38. log.info("第四个模块>>>调用消息模块打印日志>>>>>");
    39. }
    40. }
    41. 创建门面接口
    42. @Component
    43. public class PayCallbackFacade {
    44. @Autowired
    45. private LogService logService;
    46. @Autowired
    47. private PaymentService paymentService;
    48. @Autowired
    49. private IntegralService integralService;
    50. @Autowired
    51. private MsgService msgService;
    52. public boolean callbackFacade(Map<String, String> verifySignature) {
    53. logService.logService(verifySignature);
    54. paymentService.updatePaymentStatus();
    55. integralService.callIntegral();
    56. msgService.msgService();
    57. return true;
    58. }
    59. }

    4、优点
    松散耦合:使得客户端和子系统之间解耦,让子系统的内部模块更容易 扩展和维护;
    简单易用:客户端根本不知道各个子系统内部的实现,只需要与facade 交互即可;
    更好的划分访问层次:有些方法是对系统外提供的,也有些方法是内部 相互交互使用的,子系统将那些暴露给外部的功能集中到门 面中去,这样就可以实现客户端的使用,很好的隐藏了子系 统内部的实现细节。