工作五年了,居然还不懂门面模式!

大家好,我是老田,从今天开始,本公众号每周给大家送福利,送什么呢?肯定是技术书啦,不搞那么多花里胡哨的,参与方式见文末。

巩留ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为创新互联公司的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:18982081108(备注:SSL证书合作)期待与您的合作!

好啦,进入我们的主题,今天我给大家分享设计模式中的门面模式。用贴切的生活故事,以及真实项目场景来讲设计模式,最后用一句话来总结这个设计模式。

故事

开发的朋友都知道,后端开发通常都是:

controller---servie---dao/mapper/repository

但是,我问过很多人,熟悉门面模式不?有的工作五年了都不知道。

今天老田,就带你来看看门面模式。

门面模式概述

门面模式(Facade Pattern)又叫作外观模式,提供了一个统一的接口,用来访问子系统中的一群接口。其主要特征是定义了一个高层接口,让子系统更容易使用,属于结构型设计模式。

英文:

Provide a unified interface to a set of interfaces in asubsystem.Facade defines a higher-level interface that makes thesubsystem easier to use.

其实,在日常编码工作中,我们都在有意无意地大量使用门面模式。但凡只要高层模块需要调度多个子系统(2个以上类对象),我们都会自觉地创建一个新类封装这些子系统,提供精简的接口,让高层模块可以更加容易地间接调用这些子系统的功能。

生活中的案例

关于门面模式,在生活中的案例,非常之多。

案例1:去银行办理业务,有个前台接待你,然后,这个前台会问你需要办什么业务,他会一个一个带你办理,这样我们就不需要到处乱串、到处找对应业务窗口了。这个前台人员就相当于门面模式。

案例2:我们建房子,如果没有包工头的话,那就是你自己要去找水泥工,电工、装修工等。但如果有了包工头,这些活你都不用干了,直接跟包工头说,需要电工来把线路搞好。这个包工头就可以理解为门面模式。

案例3:我们后端开发的controller,也可以理解为门面模式,比如说获取用户账户信息,先查UserService获取用户信息,然后查UserAccountService用户账户信息。

门面模式适用场景

在软件系统中,门面模式适用于以下应用场景。

  • 为一个复杂的模块或子系统提供一个简洁的供外界访问的接口。
  • 希望提高子系统的独立性时。
  • 当子系统由于不可避免的暂时原因导致可能存在Bug或性能相关问题时,可以通过门面模式提供一个高层接口,隔离客户端与子系统的直接交互,预防代码污染。

门面模式通用写法

还是使用代码来实现一个简单的门面模式,因为咱们最喜欢的就是从demo开始。

业务场景:现在需要调用三个service的各自的方法:

 
 
 
 
  1. public class ServiceA { 
  2.     public void doA(){ 
  3.         System.out.println("do ServiceA"); 
  4.     } 
  5. public class ServiceB { 
  6.     public void doB(){ 
  7.         System.out.println("do ServiceB"); 
  8.     } 
  9.  
  10. public class ServiceC { 
  11.     public void doC(){ 
  12.         System.out.println("do ServiceC"); 
  13.     } 

在没有引入门面模式的时候,客户端是这么调用的:

 
 
 
 
  1. public class Client { 
  2.     public static void main(String[] args) { 
  3.         ServiceA serviceA=new ServiceA(); 
  4.         ServiceB serviceB=new ServiceB(); 
  5.         ServiceC serviceC=new ServiceC(); 
  6.  
  7.         serviceA.doA(); 
  8.         serviceB.doB(); 
  9.         serviceC.doC(); 
  10.     } 

每次,客户端自己都需要创建很多service对象,如果涉及到有很多个service,那这代码不是很尴尬吗?会出现大量重复性的代码。

运行结果

 
 
 
 
  1. do ServiceA 
  2. do ServiceB 
  3. do ServiceC 

下面我们就来加入门面模式:

 
 
 
 
  1. public class Facade { 
  2.     //是不是很像我们controller里注入各种service? 
  3.     private ServiceA serviceA = new ServiceA(); 
  4.     private ServiceB serviceB = new ServiceB(); 
  5.     private ServiceC serviceC = new ServiceC(); 
  6.  
  7.     public void doA() { 
  8.         serviceA.doA(); 
  9.     } 
  10.  
  11.     public void doB() { 
  12.         serviceB.doB(); 
  13.     } 
  14.  
  15.     public void doC() { 
  16.         serviceC.doC(); 
  17.     } 

客户端变成了:

 
 
 
 
  1. public class Client { 
  2.     public static void main(String[] args) { 
  3.         //轻轻松松的搞定,只需要创建门面这个对象即可 
  4.         Facade facade=new Facade(); 
  5.         facade.doA(); 
  6.         facade.doB(); 
  7.         facade.doC(); 
  8.     } 

运行结果:

 
 
 
 
  1. do ServiceA 
  2. do ServiceB 
  3. do ServiceC 

门面模式UML图

结合这个UML图,在回顾银行前台人员和包工头的案例,就更轻松的理解门面模式了。

门面模式中的角色

由上图可以看到,门面模式主要包含2个角色。

  • 外观角色(Facade):也叫作门面角色,是系统对外的统一接口。
  • 子系统角色(Service):可以同时有一个或多个Service。每个Service都不是一个单独的类,而是一个类的集合。Service们并不知道Facade的存在,对于Service们而言,Facade 只是另一个客户端而已(即Facade对ServiceA、ServiceB、ServiceC透明)。

门面模式的扩展

优点

● 减少系统的相互依赖   想想看,如果我们不使用门面模式,外界访问直接深入到子系统内部,相互之间是一种强耦合关系,你死我就死,你活我才能活,这样的强依赖是系统设计所不能接受的,门面模式的出现就很好地解决了该问题,所有的依赖都是对门面对象的依赖,与子系统无关。

● 提高了灵活性   依赖减少了,灵活性自然提高了。不管子系统内部如何变化,只要不影响到门面对象,任你自由活动。

● 提高安全性   想让你访问子系统的哪些业务就开通哪些逻辑,不在门面上开通的方法,你休想访问到 。

缺点

当增加子系统和扩展子系统行为时,可能容易带来未知风险。

不符合开闭原则。

某些情况下,可能违背单一职责原则。

大神们是如何使用的

在Spring中也是有大量使用到门面模式,比如说

 
 
 
 
  1. org.springframework.jdbc.support.JdbcUtils 

再来看看其中的方法

 
 
 
 
  1. public static void closeConnection(@Nullable Connection con) { 
  2.     con.close(); 
  3. public static Object extractDatabaseMetaData(DataSource dataSource, DatabaseMetaDataCallback action) 
  4.    throws MetaDataAccessException { 
  5.     Connection con = null; 
  6.   try { 
  7.    con = DataSourceUtils.getConnection(dataSource); 
  8.    DatabaseMetaData metaData = con.getMetaData(); 
  9.    if (metaData == null) { 
  10.       //..... 
  11.    } 
  12.    return action.processMetaData(metaData); 
  13.   } 
  14. ...... 

都是给我封装好了方法,对于我们开发者来说,我只面向JdbcUtils这一个类就好了,我不用去管Connection、ResultSet等是怎么创建的,需要的时候,我调用JdbcUtils的对应方法即可获得对应的对象。

在Mybatis中也是用到了门面模式,比如:

 
 
 
 
  1. org.apache.ibatis.session.Configuration 

在Configuration中以new开头的方法,比如:

 
 
 
 
  1. public Executor newExecutor(Transaction transaction) { 
  2.     return newExecutor(transaction, defaultExecutorType); 
  3. public MetaObject newMetaObject(Object object) { 
  4.     return MetaObject.forObject(object, objectFactory, objectWrapperFactory, reflectorFactory); 
  5.  
  6. public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) { 
  7.     ... 
  8.     return parameterHandler; 
  9.  
  10. public ResultSetHandler newResultSetHandler(Executor executor, MappedStatement mappedStatement, RowBounds rowBounds, ParameterHandler parameterHandler, 
  11.       ResultHandler resultHandler, BoundSql boundSql) { 
  12.    ... 
  13.     return resultSetHandler; 
  14.  
  15. public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement){ 
  16.    ... 

对于调用这些方法的地方,他并不知道是怎么new出来的对象,只管使用就行了。

在Tomcat中也有门面模式,比如:

 
 
 
 
  1. org.apache.catalina.connector.RequestFacade 

从名字就知道它用了门面模式。它封装了非常多的request操作,也整合了很多servlet-api以外的内容,给用户使用提供了很大便捷。同样,Tomcat针对Response和Session也封装了对应的ResponseFacade类和StandardSessionFacade类,感兴趣的小伙伴可以深入了解一下。

PS:基本上所有以Facade结尾的类,都是使用到了门面模式。

参考:tom的设计模式课程

总结

好了,关于门面模式就分享这么多,看完本文是不是觉得门面模式其实很简单的,另外在工作也可以考虑是不是可以把它用上,同时,面试的时候也可以用来吹吹。

最后用一句话来总结门面模式: 

打开一扇门,走向全世界。

本文转载自微信公众号「Java后端技术全栈」,可以通过以下二维码关注。转载本文请联系Java后端技术全栈公众号。

当前标题:工作五年了,居然还不懂门面模式!
URL分享:http://www.shufengxianlan.com/qtweb/news2/394502.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联