去年作大实验初次接触了装饰器模式,当时也是懵懵懂懂过去了,没有太搞明白。最近学习的时候又接触了装饰器模式,同时又有了一些新的理解。app
咱们会用到框架自带的已经封装好的方法,这节省了咱们写不少原生方法的时间,可是这些封装好的代码可能又不是十分符合咱们所须要的,咱们须要对此进行一些修改。就如同它的名字,咱们须要对封装好的代码进行一下“装饰”。
咱们本着对对修改关闭,对扩展开放的原则,对代码进行修改。在这里我举个例子。
原来有一家生产并在本地零售玻璃杯的厂家,有一天来了一个商人说要订购大量玻璃杯并运输到外地去卖,他但愿厂家能够吧生产的玻璃杯用泡沫板包装好以即可以运输。这是厂家特地开辟了一条生产线去给杯子包裹泡沫板,这时商家满意了。
商家想要买杯子,可是如今生产的杯子没有彻底获得他的满意,因而厂家在不改变原来生产线的状况下,添加了新的生产线,来知足客户需求。客户获得的仍是杯子,可是是被装饰过的杯子。这就是咱们的装饰器模式。框架
仍是那教程中例子来讲明dom
class Request { String getHeader(String key) { // 获取header值的真实代码略 } } class TokenFilterTest { /**在此传入auth-token的值*/ @Test void doFilter() { String authToken = "654321"; Request request = new Request(); this.getAuthUser(request); } /** 在此获取auth-token的值 */ void getAuthUser(Request request) { // 获取auth-token request.getHeader("auth-token"); // 根据auth-token获取当前登陆用户 } }
假设框架已经封装好了Request类和类里的getHeader方法,咱们在TokenFilterTest类里须要调用getHeader方法,可是getHeader方法是框架为咱们封装好的,咱们不能改变他的代码,可是现有的方法又打不到咱们如今的需求,咱们就为他创建一个新的类,可是必定要继承咱们原来的类。ide
class RequestWrapper extends Request { Request request; private RequestWrapper() { } public RequestWrapper(Request request) { this.request = request; } @Override String getHeader(String key) { return this.request.getHeader(key); } }
咱们经过继承Request类是能够调用getHeader方法的,可是咱们的目的是在这个方法的基础上进行改造,函数
class RequestWrapper extends Request { ... @Override String getHeader(String key) { if ("auth-token".equals(key)) { // 在此返回新的auth-token值 return "456789"; } return this.request.getHeader(key); } }
这样一个新的方法就写好了,咱们如今去调用这个方法学习
public class TokenFilterTest { @Test public void doFilter() { String authToken = new RandomString(6).nextString(); System.out.println("authToken传入值为" + authToken); Request request = new Request(); RequestWrapper requestWrapper = new RequestWrapper(request, authToken); this.getAuthUser(requestWrapper); } /** 在此获取auth-token的值 */ void getAuthUser(Request request) { // 获取auth-token System.out.println("获取到的auth-token值为:" + request.getHeader("auth-token")); // 根据auth-token获取当前登陆用户 } }
咱们发现咱们在getAuthUser方法并无改变他传入的参数类型,可是咱们在调用他的时候已经由传入request变成requestWrapper,说明咱们并无改变他的类型,可是咱们确实是用的RequestWrapper构造函数获取到的。
原来咱们三个方法的关系是这样的.
如今咱们对他装饰一下。咱们发现咱们并无改变getAuthUser。也不用改变getHeader,由于咱们的RequestWrapper类继承了Request类。this
对于装饰器模式已经有不少次接触了,每次接触都会带来新的理解,也会带来提升。spa