门面类(外观)模式(facade)
前言:
门面类模式:集成各个子系统,设置一个统一的(唯一代理)门面facade;
从你的角度,你不用很麻烦的和各个子系统交互;
从子系统的角度,他不用暴露一些他不想暴露的东西;
一、RequestFacade
代理模式?
RequestFacade实现了HttpServletRequest接口,RequestFacade代理的org.apache.catalina.connector.Request也实现了HttpServletRequest接口,综上这是一个代理模式。
org.apache.catalina.connector.Request的有些方法并没代理给RequestFacade,只有HttpServletRequest接口的方法才代理给了RequestFacade。
为何RequestFacade是门面类模式?
二、RequestFacade的应用案例
1-1,需求
向项目发出某个请求,如http://localhost:8080/oldFriend?giveMeMoney=10;
希望项目获得myMoney的value时,扩大为10倍,比如此处按道理获得的value为10,但是需求完成后,获得value为10*10=100;
1-2,原逻辑
1-3,设计方案
1-4,实现
1-4-1,统一设置giveMeMoney的值
1-4-2,重写getParameterValues方法
当key为”giveMeMoney”时,方法返回原值*10
三、重写getParameterValues方法
1,继承的方式
看到重写什么什么方法,我们首先想到的是继承;
创建一个类继承RequestFacade,然后重写getParameterValues方法。
我门的分析能力有限,直接写代码试试。
1-1,为什么我们无法获得RequestFacade代理的对象
Java对象单根继承,生成子对象前必须先生成父类对象,否则无法生成子类对象。
而生成父类对象需要传入父类中代理的那个对象。
当前倒是有一个现成的父类对象,但是这个父类对象并没有提供获取其中代理对象的途径,所以我们最终是无法获得这个代理对象的。
1-2,为什么RequestFacade不提供其代理对象的获得途径
因为这个代理对象是tomcat比较底层的,接口也比较多,tomcat并不希望你直接使用该对象,所以使用代理模式将这个对象保护了起来。
2,包装的模式
2-1,现成的包装器HttpServletRequestWrapper
四、为什么是门面类模式
RequestFacade是一个明显的代理模式;为什么作者命名为门面类模式facade?
org.apache.catalina.connector.Request被RequestFacade代理了,org.apache.catalina.connector.Request也能被其他类代理,但是我觉得可能你不会找到这个类。
也就是说org.apache.catalina.connector.Request有一个唯一的代理,即RequestFacade。
这样命名的好处是,使用org.apache.catalina.connector.Request的相关功能,不用纠结是使用proxy1,还是proxy2,还是其他,
使用统一的唯一的门面类即可,这也是门面类的特点。
总结:
RequestFacade是开放给程序员使用的,doFilter、servlet的request对象应该都是这个对象吧,
通过前面对RequestFacade类的分析,我们无法获得其内部代理的类型,我们也无法将其转型为更底层的request。
使用他的方式一般应该是继续包装他了吧。