第一、外观模式的定义
外观模式(Facade),他隐藏了系统的复杂性,并向客户端提供了一个可以访问系统的接口。这种类型的设计模式属于结构性模式。为子系统中的一组接口提供了
一个统一的访问接口,这个接口使得子系统更容易被访问或者使用。
第二、外观模式应用场景
简单来说,该模式就是把一些复杂的流程封装成一个接口供给外部用户更简单的使用。这个模式中,设计到3个角色。
1).门面角色:外观模式的核心。它被客户角色调用,它熟悉子系统的功能。内部根据客户角色的需求预定了几种功能的组合。
2).子系统角色:实现了子系统的功能。它对客户角色和Facade时未知的。它内部可以有系统内的相互交互,也可以由供外界调用的接口。
3).客户角色:通过调用Facede来完成要实现的功能。
第三、代码实现
3.1处于重构的代码
@Slf4j public class PayCallbackService { // 用户下单成功后,有那些操作? // 1.增加支付回调接口日志 // 2.修改订单数据库状态为已经成功 // 3.调用积分服务接口 // 4.调用消息服务平台服务接口 public boolean callback(Map<String, String> verifySignature) { // 1.第一步打印日志信息 String orderId = verifySignature.get("orderId"); // 获取后台通知的数据,其他字段也可用类似方式获取 String respCode = verifySignature.get("respCode"); log.info("orderId:{},respCode:{}", orderId, respCode); // 2.修改订单状态为已经支付 new PaymentTransactionMapper() { @Override public void updatePaymentStatus() { log.info(">>>修改订单状态为已经支付>>>>>"); } }.updatePaymentStatus(); // 3.调用积分接口增加积分 HttpClientUtils.doPost("jifen.com", "积分接口"); // 4.调用消息服务平台提示 HttpClientUtils.doPost("msg.com", "调用消息接口"); return true; } }
3.2重构后的代码
public class HttpClientUtils { public static String doPost(String url, String text) { System.out.println(">>>Url:{},text:{}"+ url+text); return "success"; } } @Service @Slf4j public class IntegralService { public void addIntegral() { // 3.调用积分接口增加积分 HttpClientUtils.doPost("jifen.com", "积分接口"); System.out.println(">>第三个模块:调用增加积分模块.."); } } @Service public class LogService { public void logService() { System.out.println("第一个模块:日志的收集与打印..."); } } @Service public class MsgService { public void sendMsg() { // 3.调用积分接口增加积分 HttpClientUtils.doPost("jifen.com", "积分接口"); System.out.println(">>第四个模块:调用消息服务平台模块.."); } }//门面模式 @Component public class PayFacade { @Autowired private LogService logService; @Autowired private IntegralService integralService; @Autowired private MsgService msgService; public void facadecallback() { // 1.第一步 日志收集.. logService.logService(); // 2.第三步调用积分服务接口 integralService.addIntegral(); // 3.调用消息服务平台 msgService.sendMsg(); } // 缺点:业务封装增加 }
3、3门面模式的优缺点
1、松耦合,使得客户端和子系统之间解耦,让子系统内部的模块功能更容易扩展和维护;
2、简单易用,客户端根本不需要知道子系统内部的实现,或者根本不需要知道子系统内部的构成,它只需要跟Facade类交互即可。
3、更好的划分层次,有些方法是对系统外的,有些方法是系统内部相互交互的使用的。子系统把那些暴露给外部的功能集中到门面中,
这样就可以实现客户端的使用,很好的隐藏了子系统内部的细节。