内容简介:外观模式(Facade,门面模式), 为子系统中额外一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。在项目开发和实际运用中十分频繁,但是其极易理解图例:
外观模式(Facade,门面模式), 为子系统中额外一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
在项目开发和实际运用中十分频繁,但是其极易理解
图例:
外观不只是简化了接口,也将客户从组件的子系统中解耦. 外观和适配器可以包装许多类,但是外观的意图是简化接口,而适配器的意图是将接口转换成不同接口。
场景设置
似曾相识,有个超级复杂的论坛系统(客户端调用的相当复杂)。
下面我们将直接看看旧代码怎么写的吧
UserController 主流程类
package facade; public class UserController { public static void main(String[] args) { //获取昵称 UserInfo userInfo = new UserInfo(); String userName = userInfo.getNickName(); //获取最近登录时间 UserSystem userSystem = new UserSystem(); String lastLoginTime = userSystem.lastLoginTime(); //获取用户点赞数 UserBehavior userBehavior= new UserBehavior(); int likeNum = userBehavior.getLikeNum(); //todo //其它很多小类组成了供前端渲染的数据 System.out.println("用户名" + userName + ",最近登录时间" + lastLoginTime+",喜欢了"+likeNum+"篇帖子"); } } 复制代码
相关小类
用户信息相关
package facade; public class UserInfo { public String getNickName(){ return "许仙啊"; } } 复制代码
用户系统相关:
package facade; import java.text.SimpleDateFormat; import java.util.Date; public class UserSystem { public String lastLoginTime() { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return df.format(new Date()); } } 复制代码
用户行为相关:
package facade; public class UserBehavior { public int getLikeNum() { return 5; } } 复制代码
output:
用户名许仙啊,最近登录时间2019-01-15 23:08:45,喜欢了5篇帖子 复制代码
由此结构我们可以看出,对于我们的控制器来说是比较复杂的,对象涉及的比较多,当业务比较越来越大的时候,很容易出现耦合,无法拆分,只能在控制器中另创方法.
外观模式改造
核心-外观对象
package facade; public class Facade { //用户信息对象 private UserInfo userInfo; //用户系统信息对象 private UserSystem userSystem; //用户行为对象 private UserBehavior userBehavior; public Facade() { userInfo = new UserInfo(); userSystem = new UserSystem(); userBehavior = new UserBehavior(); } public String getUserInfo() { String userName = userInfo.getNickName(); String lastLoginTime = userSystem.lastLoginTime(); int likeNum = userBehavior.getLikeNum(); //todo //其它很多小类组成了供前端渲染的数据 //可以按类别拆分到不同方法,也可以按功能需求一起,需要个人思考 return "用户名" + userName + ",最近登录时间" + lastLoginTime+",喜欢了"+likeNum+"篇帖子"; } } 复制代码
调用:
package facade; public class UserController { public static void main(String[] args) { //外观对象 Facade facade = new Facade(); System.out.println(facade.getUserInfo()); } } 复制代码
output:
用户名许仙啊,最近登录时间2019-01-15 23:19:16,喜欢了5篇帖子 复制代码
UML图(图片来自网络)
我们由前置控制器移动到了getUserInfo方法中集体封装了。可能感觉并没有什么好处,但是它完美的体现了依赖倒转原则和迪米特法则的思想。
归纳总结
看到这里相信你敢相信这也算设计模式.其实外观模式有很多种灵活的拆分方式,对于封装系统的复杂度、提供更好的小类小功能的管理还是有非常大的用处的。
上文提到了迪米特法则,指的是如果两个类不必直接通信,那么这两个类就不应当发生直接的相互作用.如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用(此文的第三者指的就是我们的外观类) --摘自《大话设计模式》
什么时候应该使用呢
其实这是个层与层关系的问题,我们的控制器层和我们的系统实现层,随着业务的复杂度上升,他们之间的关系也会越来越复杂.
增加外观Facade层,对上层提供一个简单的接口,可以减少他们的依赖.
当维护一个遗留大型系统的时候,很难再此基础上拓展它难以维护下去,可能使用外观模式是非常好的一个选择。
最后谈一下和适配器模式的区别吧
区别是适配器只是适配一个类,外观模式作用多个类?
答案不对,适配器可以适配多个类,外观模式也可以只服务一个复杂的类.主要他们的意图是不一样的,
- 适配器模式的意图是改变接口符合客户的预期
- 外观模式的意图是提供子系统的一个简化接口.
参考《大话设计模式》 《Head First设计模式》
更多精彩内容关注公众号,和最有热心的小宇作者面对面 (可搜索: 呆呆熊一点通)
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 设计模式——订阅模式(观察者模式)
- 设计模式-简单工厂、工厂方法模式、抽象工厂模式
- java23种设计模式-门面模式(外观模式)
- 设计模式-享元设计模式
- Java 设计模式之工厂方法模式与抽象工厂模式
- JAVA设计模式之模板方法模式和建造者模式
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Flask Web开发实战
李辉 / 机械工业出版社 / 2018-8-1 / 129
这是一本面向Python程序员的,全面介绍Python Web框架Flask的书。关于本书的详细介绍、相关资源等更多信息可以访问本书的官方主页http://helloflask.com/book了解。 • 国内首本Flask著作,在内容上涵盖完整的Flask Web开发学习路径,在实践上包含完整的Flask Web程序开发流程。同时兼容Python2 .7和Python3.6。 • 内......一起来看看 《Flask Web开发实战》 这本书的介绍吧!