• 装饰模式


    装饰模式(Decorator)
    定义:对象的一种结构模式
    能够动态的为一个对象添加一些额外的行为职责
    继承也可以实现上述功能,但是这是一个编译器的扩展而不是运行期的扩展模式.装饰模式正是为了解决“过渡依赖使用继承来进行对象的的功能扩展”而时设的
    目的:进行对象行为职责扩展
    特性:动态(扩展特性在运行期自动获得)
    这是装饰模式的基本实现中所涉及的角色:
    原始接口(Component):定义了一个接口方法
    默认目标实现类(TargetComponent):对于原始接口的默认实现方式。在装饰模式中,默认目标实现类被认为是有待扩展的类,器方法operation被认为是有待扩展的行为方法。
    装饰实现类(ComponentDecorator):同样实现了原始接口,既可以是一个抽象类,也可以是一个具体实现类。其内部封装了一个原始接口的对象实例:targetComponent,这个实例的实现往往被初始化成默认目标实现类(TargetComponent)
    具体装饰实现类(ComponentDecoratorA,ComponentDecoratorB):集成子装饰类,我们可以在operations方法中调用原始接口的对象实例targetComponent获得默认目标实现类的行为方式并在其中加入行为扩展实现,也可以自由添加新的行为addBehaviorA等。
     
    装饰模式的构成要素:
    默认目标实现(TargetComponent)类封装于具体的装饰实现类(ComponentDecorator)或者其子类的内部,从而形成对象之间的引用关系
    具体装饰实现类(ComponentDecorator)同样实现了原始接口(Component)
    例如:servlet标准接口设计中,天然包含了对HttpServletRequest和HttpServletResponse这两大接口的装饰实现类
    HttpServletRequest和HttpServletResponse是Servlet标准所指定的Java语言与Web容器进行交互的接口,接口本身只规定Java语言对web容器进行访问的行为方式,而具体的实现是由不同的web容器在其内部实现的。例如,Tomcat Weblogic或者Websphere等不同的web容器对HttpServletRequest和HttpServletResponse的实现解释不同。
    那么在运行期间,当我们需要对HttpServletRequest或HttpServletResponse的默认客观实现行为进行扩展时我们就可以继承HttpServletRequestWrapper或者HttpServletResponseWrapper来实现。事实上,无论是HttpServletRequestWrapper和HttpServletResponseWrapper,他们都提供了一个可传入对应HttpServletRequest和HttpServletResponse接口的构造函数,并在构造函数中实现了将原始HttpServletRequest和HttpServletResponse接口的实现封装于内部的基本逻辑。
     
    装饰模式作为对象行为的扩展方式比继承更合理的地方:虽然装饰模式产生的初衷是装饰类对默认目标实现类的行为扩展,然而装饰类却并不对默认目标实现类形成依赖。
     
    package com.slp.Decorator;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    
    public class SampleRequestWrapper extends HttpServletRequestWrapper {
    	private CacheManager cacheManager;
    
    	public SampleRequestWrapper(HttpServletRequest request) {
    		super(request);
    		// TODO Auto-generated constructor stub
    	}
    
    	/**
    	 * 根据key值 首先在cache中查找,再调用基类方法查找
    	 */
    	public Object getAttribute(String s) {
    		if (s != null && s.startsWith("cacheable")) {
    			String cacheKey = s.substring("cacheable.".length());
    			return cacheManager.getValue(cacheKey);
    		} else {
    			return super.getAttribute(s);
    		}
    	}
    }
    

      

    有了这个类之后,我们就可以在处理URL请求的Filter中将原始的HttpServletRequest替换成这个装饰实现类。

    package com.slp.Decorator;
    
    import java.io.IOException;
    
    import javax.servlet.FilterChain;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    
    public class SampleFilter {
    
    	public void doFilter(ServletRequest req,ServletResponse res,FilterChain chain) throws IOException, ServletException{
    		
    		HttpServletRequest request=(HttpServletRequest)req;
    		request=new SampleRequestWrapper(request);
    		chain.doFilter(request, res);
    	}
    }
    

      这样的话,我们就在整个Request生命周期获得了HttpServletRequest的扩展:因为对于HttpServletRequest来说,其原生的getAttribute方法的行为被加入了从缓存中读取数据的新特性。

    这也实现了对默认目标实现进行选择性扩展 
  • 相关阅读:
    PHP审计之POP链挖掘
    PHP审计之PHP反序列化漏洞
    Centos虚拟机IP配置以及Tenginx安装部署
    VMware下载安装与CentOS虚拟机安装
    重学c#系列——list(十二)
    整理k8s————k8s prod相关[三]
    重学c#系列——字典(十一)
    整理k8s————k8s组件[二]
    整理k8s————k8s概念[一]
    mysql 必知必会整理—数据库的维护[十八]
  • 原文地址:https://www.cnblogs.com/dream-to-pku/p/5565763.html
Copyright © 2020-2023  润新知