外观模式(Facade),他隐藏了系统的复杂性,并向客户端提供了一个能够访问系统的接口。这种类型的设计模式属于结构性模式。为子系统中的一组接口提供了一个统一的访问接口,这个接口使得子系统更容易被访问或者使用。 web
简单来讲,该模式就是把一些复杂的流程封装成一个接口供给外部用户更简单的使用。这个模式中,设计到3个角色。spring
1.门面角色:外观模式的核心。它被客户角色调用,它熟悉子系统的功能。内部根据客户角色的需求预约了几种功能的组合。数据库
2.子系统角色:实现了子系统的功能。它对客户角色和Facade时未知的。它内部能够有系统内的相互交互,也能够由供外界调用的接口。设计模式
3.客户角色:经过调用Facede来完成要实现的功能。app
须要重构代码ide
@Slf4j @Component 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; } }
utilsspring-boot
@Slf4j public class HttpClientUtils { public static String doPost(String url, String text) { log.info(">>>Url:{},text:{}", url, text); return "success"; } }
建立业务逻辑封装post
@Slf4j @Component public class LogService { public void log(Map<String, String> verifySignature) { String orderId = verifySignature.get("orderId"); // 获取后台通知的数据,其余字段也可用相似方式获取 String respCode = verifySignature.get("respCode"); log.info("1.第一个模块,打印日志模块:orderId:{},respCode:{}", orderId, respCode); } }
@Slf4j @Component public class PaymentService { public void updatePaymentStatus() { // 2.修改订单状态为已经支付 new PaymentTransactionMapper() { @Override public void updatePaymentStatus() { log.info(2."第二个模块>>>修改订单状态为已经支付>>>>>"); } }.updatePaymentStatus(); } }
@Component @Slf4j public class IntegralService { public void callIntegral() { // 3.调用积分接口增长积分 HttpClientUtils.doPost("jifen.com", "积分接口"); log.info("3.第三个模块>>>调用积分接口打印日志>>>>>"); } }
@Component @Slf4j public class MsgService { public void callMsg() { log.info("4.第四个模块 调用消息模块"); HttpClientUtils.doPost("msg.com", "调用消息接口"); } }
建立门面接口:PayFacade 测试
@Component public class PayFacade { @Autowired private LogService logService; @Autowired private PaymentService paymentService; @Autowired private IntegralService integralService; @Autowired private MsgService msgService; public String callback(Map<String, String> verifySignature) { logService.log(verifySignature); paymentService.updatePaymentStatus(); integralService.callIntegral(); msgService.callMsg(); return "success"; } }
PayCallbackController url
@RestController public class PayCallbackController { @Autowired private PayFacade payFacade; @RequestMapping("/callback") public String callback(@RequestBody Map<String, String> verifySignature) { String result = payFacade.callback(verifySignature); return result; } }
mapper
public interface PaymentTransactionMapper { void updatePaymentStatus(); }
启动类
@SpringBootApplication public class AppFacade { public static void main(String[] args) { SpringApplication.run(AppFacade.class); } }
pom
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.1.RELEASE</version> </parent> <dependencies> <!-- sprinboot web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.10</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency> </dependencies>
使用postman进行测试
控制台输出
2019-05-25 23:12:54.773 INFO 1948 --- [nio-8080-exec-6] com.xuyu.service.LogService : 1.第一个模块,打印日志模块:orderId:111,respCode:xuyucode
2019-05-25 23:12:54.774 INFO 1948 --- [nio-8080-exec-6] com.xuyu.service.PaymentService : 2.第二个模块>>>修改订单状态为已经支付>>>>>
2019-05-25 23:12:54.775 INFO 1948 --- [nio-8080-exec-6] com.xuyu.service.IntegralService : 3.第三个模块 调用积分模块
2019-05-25 23:12:54.775 INFO 1948 --- [nio-8080-exec-6] com.xuyu.utils.HttpClientUtils : >>>Url:jifen.com,text:积分接口
2019-05-25 23:12:54.775 INFO 1948 --- [nio-8080-exec-6] com.xuyu.service.MsgService : 4.第四个模块 调用消息模块
2019-05-25 23:12:54.775 INFO 1948 --- [nio-8080-exec-6] com.xuyu.utils.HttpClientUtils : >>>Url:msg.com,text:调用消息接口
success
优势
松散耦合:使得客户端和子系统之间解耦,让子系统内部的模块功能更容易扩展和维护;
简单易用:客户端根本不须要知道子系统内部的实现,或者根本不须要知道子系统内部的构成,它只须要跟Facade类交互便可。
更好的划分访问层次:有些方法是对系统外的,有些方法是系统内部相互交互的使用的。子系统把那些暴露给外部的功能集中到门面中,这样就能够实现客户端的使用,很好的隐藏了子系统内部的细节。
版权@须臾之余https://my.oschina.net/u/3995125