当前位置: 首页 > 后端技术 > Java

原来你不知道你每天都在使用门面模式

时间:2023-04-01 20:48:53 Java

1使用门面模式集成已知的API函数一般的电商平台集成了很多子系统,形成了一个庞大的购物平台。在某些情况下,很多现有的功能不是重新开发,而是要连接到现有的子系统。这些子系统可能涉及积分系统、支付系统、物流系统的接口调用。如果所有的接口调用都由前端发送去调用已有的接口,会增加前端开发人员的难度,还会增加一些网络请求,影响页面的性能。这时候就可以利用门面模型了。将所有现成的接口集成到一个类中,后端提供统一的接口供前端调用,前端开发者无需关心各个接口的业务关系,只需要专注于页面交互.我们用代码模拟一个积分换礼物的业务场景。首先创建礼物实体类GiftInfo。公共类GiftInfo{私有字符串名称;publicGiftInfo(Stringname){this.name=name;}publicStringgetName(){返回名称;}}然后编写各个子系统的业务逻辑代码,创建积分系统QualifyService类。publicclassQualifyService{publicbooleanisAvailable(GiftInfogiftInfo){System.out.println("验证"+giftInfo.getName()+"积分资质通过,库存通过");返回真;}}创建支付系统PaymentService类。publicclassPaymentService{publicbooleanpay(GiftInfopointsGift){//扣分System.out.println("支付"+pointsGift.getName()+"扣分成功");返回真;}}创建物流系统的ShippingService类。publicclassShippingService{//deliverypublicStringdelivery(GiftInfogiftInfo){//物流系统对接逻辑System.out.println(giftInfo.getName()+"进入物流系统");StringshippingOrderNo="666";退货订单号;}}接下来创建外观角色GiftFacadeService类,只开启一个exchange()方法用于交换礼物,将三个子系统的所有功能都集成在exchange()方法内部。公共类GiftFacadeService{privateQualifyServicequalifyService=newQualifyService();privatePaymentServicepointsPaymentService=newPaymentService();私人运输服务shippingService=newShippingService();//exchangepublicvoidexchange(GiftInfogiftInfo){if(qualifyService.isAvailable)(gi){//资格验证通过if(pointsPaymentService.pay(giftInfo)){//如果积分支付成功StringshippingOrderNo=shippingService.delivery(礼物信息);System.out.println("物流系统下单成功,订单号为:"+shippingOrderNo);}}}}最后看客户端代码。publicstaticvoidmain(String[]args){GiftInfogiftInfo=newGiftInfo("《Spring 5核心原理》");GiftFacadeServicegiftFacadeService=newGiftFacadeService();giftFacadeService.exchange(giftInfo);}运行结果如下图所示。通过这样的案例对比,相信大家对门面模型印象非常深刻。2门面模式在Spring源码中的应用我们先来看一下SpringJDBC模块下的JdbcUtils类,它封装了所有与JDBC相关的操作。代码片段如下。公共抽象类JdbcUtils{publicstaticfinalintTYPE_UNKNOWN=-2147483648;privatestaticfinalLoglogger=LogFactory.getLog(JdbcUtils.class);publicJdbcUtils(){}publicstaticvoidcloseConnection(Connectioncon){if(con!=null){try{con.close();}catch(SQLExceptionvar2){logger.debug("无法关闭JDBC连接",var2);}catch(Throwablevar3){logger.debug("关闭JDBC连接时发生意外异常",var3);}}}publicstaticvoidcloseStatement(Statementstmt){if(stmt!=null){try{stmt.close();}catch(SQLExceptionvar2){logger.trace("无法关闭JDBC语句",var2);}catch(Throwablevar3){logger.trace("关闭JDBC语句时发生意外异常",var3);}}}publicstaticvoidcloseResultSet(ResultSetrs){if(rs!=null){try{rs.close();}catch(SQLExceptionvar2){logger.trace("无法关闭JDBCResultSet",var2);}catch(Throwablevar3){logger.trace("关闭JDBCResultSet时发生意外异常",var3);}}}...}更多其他的操作,看它的结构就很清楚了,如下图3Facade模式在MyBatis源码中的应用我们来看看MyBatis中的Configuration类。以new开头的方法有很多。源代码如下。publicMetaObjectnewMetaObject(Objectobject){returnMetaObject.forObject(object,this.objectFactory,this.objectWrapperFactory,this.reflectorFactory);}publicParameterHandlernewParameterHandler(MappedStatementmappedStatement,ObjectparameterObject,BoundSqlboundSql){ParameterHandlerparameterHandler=mappedStatement.getLang().createParameterHandler(mappedStatement,parameterObject,boundSql);parameterHandler=(ParameterHandler)this.interceptorChain.pluginAll(parameterHandler);返回参数处理程序;}publicResultSetHandlernewResultSetHandler(Executorexecutor,MappedStatementmappedStatement,RowBoundsrowBounds,ParameterHandlerparameterHandler,ResultHandlerresultHandler,BoundSqlboundSql){ResultSetHandlerresultSetHandler=newDefaultResultSetHandler(执行器,mappedStatement,parameterHandler,resultHandler,boundSql,行边界);ResultSetHandlerresultSetHandler=(ResultSetHandler)this.interceptorChain.pluginAll(resultSetHandler);返回结果集处理程序;}publicStatementHandlernewStatementHandler(Executor执行器,MappedStatementmappedStatement,ObjectparameterObject,RowBoundsrowBounds,ResultHandlerresultHandler,BoundSqlboundSql){StatementHandlerstatementHandler=(StatementHandler)this.interceptorChain.pluginAll(statementHandler);返回语句处理程序;}publicExecutornewExecutor(Transactiontransaction){returnthis.newExecutor(transaction,this.defaultExecutorType);}上面这些方法都是对JDBC中关键组件操作的封装4门面模式在Tomcat源码中的应用另外,门面模式在Tomcat源码中也有所体现,这也很有意思。以RequestFacade类为例,查看其源码。公共类RequestFacade实现HttpServletRequest{...@OverridepublicStringgetContentType(){if(request==null){thrownewIllegalStateException(sm.getString("requestFacade.nullRequest"));}返回请求.getContentType();}@OverridepublicServletInputStreamgetInputStream()throwsIOException{if(request==null){thrownewIllegalStateException(sm.getString("requestFacade.nullRequest"));}返回请求.getInputStream();}@OverridepublicStringgetParameter(Stringname){if(request==null){thrownewIllegalStateException(sm.getString("requestFacade.nullRequest"));}if(Globals.IS_SECURITY_ENABLED){returnAccessController.doPrivileged(newGetParameterPrivilegedAction(name));}别的{返回请求.getParameter(名称);}}...}从名字就可以看出它采用了门面模式,封装了很多请求操作,也集成了很多servlet-api以外的内容,为用户提供了很多方便。同样,Tomcat也为Response和Session封装了相应的ResponseFacade类和StandardSessionFacade类。有兴趣的小伙伴可以详细了解一下。小伙伴们,是不是无意中发现自己每天都在使用门面模式呢?【推荐】汤姆炸弹架构:设计模式30个真实案例,挑战60W年薪不是梦本文为汤姆炸弹架构,转载请注明出处。科技在于分享,我分享我的快乐!如果本文对您有帮助,请关注并点赞;有什么建议也可以留言或私信。您的支持是我坚持创作的动力。关注微信公众号『汤姆炸弹建筑』,获取更多技术干货!