设计模式 = 装饰者模式 与 动态代理模式在Java中的使用

装饰者模式:

定义

在不改变原有对象的基础之上,将功能附加到对象上。提供了比继承更有弹性的替代方案(扩展原有对象功能)

类型

结构型

适用场景

  1. 扩展一个类的功能或者给一个类添加附加职责
  2. 给一个对象动态的添加功能,或动态撤销功能。

动态代理模式:

定义

代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。通俗的来讲代理模式就是我们生活中常见的中介。代理模式是常用的结构型设计模式之一,它为对象的间接访问提供了一个解决方案,可以对对象的访问进行控制。代理模式类型较多,其中远程代理、虚拟代理、保护代理等在软件开发中应用非常广泛。

类型

结构型

适用场景

1:类中的方法批量处理

2:方法的区分处理

3:当我们想要隐藏某个类,或者这个类中的部分方法

4:扩展功能

通过一个代理类完成全部的代理功能,那么我们就需要用动态代理.
一个代理只能代理一种类型,而且是在编译器就已经确定被代理的对象。而动态代理是在运行时,通过反射机制实现动态代理,并且能够代理各种类型的对象
在Java中要想实现动态代理机制,需要java.lang.reflect.InvocationHandler接口和 java.lang.reflect.Proxy类的支持。

为什么要使用代理模式?

  • 中介隔离作用:在某些情况下,一个客户类不想或者不能直接引用一个委托对象,而代理类对象可以在客户类和委托对象之间起到中介的作用,其特征是代理类和委托类实现相同的接口。
  • 开闭原则,增加功能:代理类除了是客户类和委托类的中介之外,我们还可以通过给代理类增加额外的功能来扩展委托类的功能,这样做我们只需要修改代理类而不需要再修改委托类,符合代码设计的开闭原则。代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后对返回结果的处理等。代理类本身并不真正实现服务,而是同过调用委托类的相关方法,来提供特定的服务。真正的业务功能还是由委托类来实现,但是可以在业务功能执行的前后加入一些公共的服务。例如我们想给项目加入缓存、日志这些功能,我们就可以使用代理类来完成,而没必要打开已经封装好的委托类。

================================================================================================================================================================================================

案例:装饰者模式:

Test.java

public class Test {
    public static void main(String[] args) {

        LvJing lvJing = new LvJing(new iPhone());
        lvJing.takePhone();

    }
}

Phone.java

public interface Phone {

    public void takePhone();

    public void call();
}

iPhone.java

public class iPhone implements Phone{
    @Override
    public void takePhone() {
        System.out.println("iphone拍照");
    }

    @Override
    public void call() {
        System.out.println("iphone打电话");
    }
}
iPhoneWrap.java

public  abstract class iPhoneWrap implements Phone {

    private  Phone phone;
    public iPhoneWrap(Phone phone ) {
        this.phone = phone;
    }


    @Override
    public void takePhone() {
        phone.takePhone();
    }

    @Override
    public void call() {
        phone.call();
    }
}
MeiYan.java

public class MeiYan extends iPhoneWrap {
    public MeiYan(Phone phone) {
        super(phone);
    }

    @Override
    public void takePhone() {
        super.takePhone();
        System.out.println("增加美颜功能");
    }
}

 此案例就是对装饰者模式的基础,还可以进行增加扩展功能、

Filter装饰者模式的应用:

@WebFilter("/WordsProServlet")
public class WordsProFilter implements Filter {
    private List<String> wordsList;
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        HttpMyRequest httpMyRequest = new HttpMyRequest(request, wordsList);
        String content = httpMyRequest.getParameter("content");
        chain.doFilter(httpMyRequest, response);
    }

    public void init(FilterConfig config) throws ServletException {
        System.out.println("=======WordsProFilter=========过滤器=================");
        Properties properties = new Properties();
        InputStream words = this.getClass().getResourceAsStream("/words.properties");
        try {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(words, "utf-8"));
            properties.load(bufferedReader);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String keywords = properties.getProperty("keywords");
        List<String> wordsList = Arrays.asList(keywords.split(","));
        this.wordsList = wordsList;
    }
}

装饰模式的扩展类:对HttpServletRequest 进行扩展

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.List;

public class HttpMyRequest extends HttpServletRequestWrapper {

    private List<String> wordsList;

    public HttpMyRequest(HttpServletRequest request,List<String> list) {
        super(request);
        this.wordsList =list;
    }

    @Override
    public String getParameter(String name) {
      String content =  super.getParameter(name);
        for (String word : wordsList) {
            if (content.contains(word)){
                String flagStr ="";
                for (int i = 0; i < word.length(); i++) {
                    flagStr+="*";
                }
                content = content.replaceAll(word,flagStr);
            }
        }
        return content;
    }
}

================================================================================================================================================================================================

动态代理模式实现案例:

实现步骤:JDK:要求目标对象和代理对象,实现同一个接口

1.创建目标对象(过滤器已提供)
2.通过Proxy工具,生产代理类,创建代理对象
3.放行代理对象

通过Proxy代理实现过滤:

@WebFilter("/WordsProProxyFilter")
public class WordsProProxyFilter implements Filter {
    private List<String> wordsList;

    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //设置请求解码方式
        req.setCharacterEncoding("utf-8");
        //设置响应编码方式
        resp.setContentType("text/html;charset=utf-8");

    // 1.创建目标对象(过滤器已提供   ServletRequest req)
        // 2.通过Proxy工具,生产代理类,创建代理对象
        /*
                类加载器:目标对象的加载器
                接口数组:目标对象的接口数组
                处理器接口:创建匿名内部类,实现增强业务逻辑
         */
        ServletRequest servletRequest =(ServletRequest) Proxy.newProxyInstance(req.getClass().getClassLoader(), req.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                //目标对象实现具体功能
                Object object = method.invoke(req, args);
                //如果执行了getParameter方法,,实现对内容增强,过滤
                if ("getParameter".equals(method.getName())){
                    String msg = (String) object;
                    for (String word : wordsList) {
                        if (msg.contains(word)){
                            msg=msg.replaceAll(word,"***");
                        }
                    }
                    //返回结果
                    return msg;
                }
                //返回结果
                return object;
            }
        });
        //放行代理对象
        chain.doFilter(servletRequest, resp);
    }

    public void init(FilterConfig config) throws ServletException {
        System.out.println("=======WordsProProxyFilter=========过滤器=================");
        Properties properties = new Properties();
        InputStream words = this.getClass().getResourceAsStream("/words.properties");
        try {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(words, "utf-8"));
            properties.load(bufferedReader);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String keywords = properties.getProperty("keywords");
        List<String> wordsList = Arrays.asList(keywords.split(","));
        this.wordsList = wordsList;
    }

}

资料:

代理模式

代理模式1

发布了141 篇原创文章 · 获赞 27 · 访问量 27万+

猜你喜欢

转载自blog.csdn.net/u010581811/article/details/105729981