设计模式-外观模式及应用

  外观模式,有的资料也叫做“门面模式”,外观模式使用比较简单,使用的频率也不高,主要是这个思想。
  举个生活中的例子,我们知道之前如果办理个证件后者手续,没有互联网之前,我们要各个单位部门的跑,可能一趟还不行;之前不是网上吐槽政府机构办事效率的问题,就是为了证明“我是我自己”。
  现在各个行业都走上了信息化,不用来回跑,直接在网上就能办好很多事情,当然也不乏需要去现场的。大家手机里都会有支付宝这个APP,上面的“市民中心模块”,功能涵盖了很多我们常办的事情,什么生活缴费、社保办理查询、公积金查询提取、人才就业…等等。这些子功能我们进去后,会跳转到指定的办事页面;虽然是不同的系统提供的,但是入口现在只有一个“市民中心”。
  回到软件设计层面,什么时候会使用到这个场景呢,前面说到我们的设计规范中有说“接口职责单一性”问题,这带来的问题可能就是接口的颗粒度已经很细,如果一个业务需要设计多个接口的调用,势必会增加客户端或者调用者的使用复杂多。如果我们的接口更改,调用者也需要跟着修改,也违背了设计规范的“开闭原则”。这时可以根据业务将部分职责单一的接口聚合,暴露给使用者(这里的聚合类就是我们的门面),使用者只需要调门面提供的接口,后续更改了相关业务,我们的门面无需修改,功能一样提供,也满足我们的开闭原则。但是如果增加其子接口的话,可能需要更改门面。

外观模式的结构与实现

1.模式结构
外观(Facade)模式包含以下主要角色。

  • 外观(Facade)角色:为多个子系统(或接口)对外提供一个共同的接口。
  • 子系统(Sub System)角色:实现系统的部分功能,使用者通过外观角色访问它。
  • 使用者(Client)角色:通过一个外观角色访问各个子系统的功能。

外观模式结构图:
在这里插入图片描述

案例代码:
这里就按照本文开头举支付宝的案例来实现以下外观模式的使用

  • 子系统角色1 公积金办理中心
public class AccumulationDund {
	
	public void transaction(){
		System.out.println("公积金管理中心-公积金业务");
	}
}
  • 子系统角色2 社保办理中心
public class SocialSecurity {
	
	public void transaction(){
		System.out.println("社保中心-社保业务");
	}
}
  • 子系统角色3 手机充值中心
public class MobileTopup {
	
	public void transaction(){
		System.out.println("手机充值中心-手机充值业务");
	}
}
  • 观察者角色 支付宝APP 市民中心
public class ZFBFacade {
	private SocialSecurity socialSecurity;
	
	private AccumulationDund accumulationDund;
	
	private MobileTopup mobileTopup;

	public ZFBFacade(SocialSecurity socialSecurity, AccumulationDund accumulationDund, MobileTopup mobileTopup) {
		super();
		this.socialSecurity = socialSecurity;
		this.accumulationDund = accumulationDund;
		this.mobileTopup = mobileTopup;
	}
	
	//业务中心
	public void businessCenter(){
		//社保业务
		socialSecurity.transaction();
		//公积金业务
		accumulationDund.transaction();
		//手机充值业务
		mobileTopup.transaction();
	}
}
  • client 使用者
public class Client {
	
	public static void main(String[] args) {
		SocialSecurity socialSecurity = new SocialSecurity();
		AccumulationDund accumulationDund = new AccumulationDund();
		MobileTopup mobileTopup = new MobileTopup();
		
		ZFBFacade zfbFacade = new ZFBFacade(socialSecurity, accumulationDund, mobileTopup);
		zfbFacade.businessCenter();
	}
}

执行结果:

 社保中心-社保业务
 公积金管理中心-公积金业务
 手机充值中心-手机充值业务

案例结构图:
在这里插入图片描述

外观模式的优缺点

外观(Facade)模式是“迪米特法则”的典型应用,它有以下主要优点。

  • 降低了子系统与客户端之间的耦合度,使得子系统的变化不会影响调用它的客户类。
  • 对客户屏蔽了子系统组件,减少了客户处理的对象数目,并使得子系统使用起来更加容易。

外观(Facade)模式的主要缺点如下。

  • 不能很好地限制客户使用子系统类,很容易带来未知风险;
  • 门面模式需要适配哪些子系统,增加了门面的设计难度;
  • 增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。
外观模式的使用场景

通常在以下情况下可以考虑使用外观模式。

  • 对分层结构系统构建时,使用外观模式定义子系统中每层的入口点可以简化子系统之间的依赖关系;
  • 当一个复杂系统的子系统很多时,外观模式可以为系统设计一个简单的接口供外界访问;
  • 当使用方如果调用多个子系统,多次网络交互可能影响其整个服务的性能,可以通过门面的方式,减少不必要的网络开销。
外观模式在源码中的应用

1.Tomcat源码中的使用
在tomcat中大量的使用了外观模式,这里举一个案例
tomcat使用外观模式对Request进行包装,首先看下类图
在这里插入图片描述

参考网上资料
org.apache.coyote.Request是应用层拿到的Request对象的底层实现,不便使用。
org.apache.catalina.connector.Request类封装了org.apache.coyote.Request类,实现了HttpServletRequest接口,已经具备了实际使用能力,不过它还包含了很多Catalina的方法,,这些方法不应该暴露给应用层,以免引起与其他容器实现的兼容性问题。
org.apache.catalina.connector.RequestFacade类,实现了HttpServletRequest接口,并在其中包含了一个org.apache.catalina.connector.Request对象,将所有HttpServletRequest接口的调用,都代理给org.apache.catalina.connector.Request对象来处理,这样就屏蔽了Catalina的相关的内部方法,使用户可以专注于servlet的标准方法。

✨✨ 欢迎🔔订阅个人的微信公众号 享及时博文更新
个人工作号

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值