码迷,mamicode.com
首页 > 其他好文 > 详细

装饰者模式

时间:2017-08-10 21:04:28      阅读:192      评论:0      收藏:0      [点我收藏+]

标签:blog   pack   load   stack   rgs   lan   package   super   todo   

 

定义:动态给一个对象添加一些额外的职责,就象在墙上刷油漆.使用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
        
    }

    
}

 

装饰者模式

标签:blog   pack   load   stack   rgs   lan   package   super   todo   

原文地址:http://www.cnblogs.com/qlqwjy/p/7340947.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!