首页 > 代码库 > 装饰者模式

装饰者模式

 

定义:动态给一个对象添加一些额外的职责,就象在墙上刷油漆.使用Decorator模式相比用生成子类方式达到功能的扩充显得更为灵活。

  设计初衷:通常可以使用继承来实现功能的拓展,如果这些需要拓展的功能的种类很繁多,那么势必生成很多子类,增加系统的复杂性,同时,使用继承实现功能拓展,我们必须可预见这些拓展功能,这些功能是编译时就确定了,是静态的。

  

   要点: 装饰者与被装饰者拥有共同的超类(继承同一父类或实现同一接口),继承的目的是继承类型,而不是行为

 

Java中增强一个类的对象方法有三种:

1. 继承或者实现接口:A对象继承a对象类,然后重写fun1(),就是增强了这个方法,如果a是接口,就无法用继承增强。

2.装饰者模式:

  (1)增强类与被增强类实现同一接口(继承同一父类)

  (2)增强类中传入被增强类对象

  (3)需要增强的重写,不需要的调用被增强对象的。

3.动态代理:

  动态代理与装饰者模式比价相似,而且通过反射完成。

 

 

一个基于装饰者模式的编码过滤器

package web.filter;import java.io.IOException;import java.io.UnsupportedEncodingException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;public class EncodingFilter implements Filter{        @Override    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)            throws IOException, ServletException {                //request.setCharacterEncoding("UTF-8");                //在传递request之前对request的getParameter方法进行增强        /*         * 装饰者模式(包装)         *          * 1、增强类与被增强的类要实现统一接口         * 2、在增强类中传入被增强的类         * 3、需要增强的方法重写 不需要增强的方法调用被增强对象的         *          */                //被增强的对象        HttpServletRequest req = (HttpServletRequest) request;        //增强对象        EnhanceRequest enhanceRequest = new EnhanceRequest(req);                        chain.doFilter(enhanceRequest, response);            }    @Override    public void destroy() {            }        @Override    public void init(FilterConfig filterConfig) throws ServletException {            }}class EnhanceRequest extends HttpServletRequestWrapper{   //这个类允许你只重写想增强的方法        private HttpServletRequest request;    public EnhanceRequest(HttpServletRequest request) {        super(request);        this.request = request;    }        //对getParaameter增强    @Override    public String getParameter(String name) {        String parameter = request.getParameter(name);//乱码        try {            parameter = new String(parameter.getBytes("iso8859-1"),"UTF-8");        } catch (UnsupportedEncodingException e) {            e.printStackTrace();        }        return parameter;    }    }

 

 

 

基于动态代理的编码过滤器:

package filter;import java.io.IOException;import java.io.UnsupportedEncodingException;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;import com.sun.corba.se.impl.protocol.giopmsgheaders.ReplyMessage_1_0;public class EncodingFilter2 implements Filter{    @Override    public void init(FilterConfig filterConfig) throws ServletException {        // TODO Auto-generated method stub            }    @Override    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)            throws IOException, ServletException {    HttpServletRequest req = (HttpServletRequest) request;            HttpServletRequest enhanceRequset = (HttpServletRequest) Proxy.newProxyInstance(            req.getClass().getClassLoader(),             req.getClass().getInterfaces(),            new InvocationHandler() {                                @Override                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//                    对getParameter进行增强                    if(method.getName().equals("getParameter")){                        String invoke = (String) method.invoke(req, args);//乱码                        invoke = new String(invoke.getBytes("iso8859-1"),"UTF-8");//转码                        return invoke;                    }                    return method.invoke(req, args);                }            });        chain.doFilter(enhanceRequset, response);    }    @Override    public void destroy() {        // TODO Auto-generated method stub            }    }

 

装饰者模式