设计模式之代理模式

Posted icanner

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式之代理模式相关的知识,希望对你有一定的参考价值。

一 : 什么是代理(Proxy)模式?

代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。通俗讲.就是真正的业务功能还是由委托类来实现,但是在实现业务之前的一些公共服务,例如在项目开发中忘记了加入缓冲、日志等的功能。后期想加入,就可以使用代理来实现而没有必要打开已经封装好的委托类。

现实生活中的代理模式:房东-->中介-->租客 中介就是代理方,负责看房,谈价格,签合同等琐事,房东只需收钱.

二 : 为什么要有代理模式?

(1).职责清晰:真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。
(2).代理对象可以在客户端和目标对象之间起到中介的作用,客户端使用的是代理对象中的方法,这样起到了中介的作用和保护了目标对象的作用。
(3).高拓展性:无论被代理对象如何改变,只要代理类和被代理类都实现了统一接口,都不同修改代理类,而且即使扩展了新的被代理类,代理类也可以使用,只要创建代理类的时候传入对应的被代理类对象。

三 : 怎么使用代理模式?

3.1 静态代理 

  静态代理定义 : 静态代理是由程序员创建或特定工具自动生成源代码,再对其编译。最大的特点就是在程序运行时代理类的.class文件就已经存在了,但是这有一个很大的缺陷即每一个代理类只能为一个接口服务。

3.1.1 静态代理示例:

①:定义服务接口

package com.canner.proxy;

/**
 * @Auther: canner
 * @Date: 12:18 2018/11/02 
 */
public interface ICustomer {
    void buyHosue();
}

②:定义服务实现类

import com.canner.proxy.ICustomer;

/**
 * @Auther: canner
 * @Date: 12:20 2018/11/02 
 */
public class CustomerImpl implements ICustomer{

    @Override
    public void buyHosue() {
        System.out.println("顾客买了一套房");
    }
}

③:创建客户代理类

package com.canner.proxy;

import com.canner.proxy.ICustomer;

/**
 * @Auther: canner
 * @Date: 12:33 2018/11/02 
 */
public class CustomerProxy implements ICustomer{

    private ICustomer customer;

    public CustomerProxy(final ICustomer customer) {
        this.customer= customer;
    }

    @Override
    public void buyHosue() {
        System.out.println("客户买房前做的事情");
        customer.buyHosue();
        System.out.println("客户买房后做的事情");

    }
}

④:编写测试

/**
 * @Auther: canner
 * @Date: 12:25 2018/11/02
 */
public class ProxyTest {
    public static void main(String[] args) {
        ICustomer customer = new CustomerImpl();
        CustomerProxy customerProxy = new CustomerProxy(customer);
        customerProxy.buyHosue();
    }
}

静态代理总结:代理对象和实际对象实现的是同一个接口

优点:可以做到在符合开闭原则的情况下对目标对象进行功能扩展。

缺点:1:每一个代理类只能为一个接口服务,工作量太大,不易管理。同时接口一旦发生改变,代理类也得相应修改。 

      2:在程序运行之前静态代理的.class文件已经存在了。

           3:如果接口新增一个方法,代理类也得维护新增内容。

3.2 动态代理

3.2.1 JDK动态代理

动态代理 : 在动态代理中我们不再需要再手动的创建代理类,我们只需要编写一个动态处理器就可以了。真正的代理对象由JDK在运行时利用反射为我们动态的来创建。

JDK 动态代理 API 分析:(必须要求真实对象是有接口)

1java.lang.reflect.Proxy :Java 动态代理机制生成的所有动态代理类的父类,它提供了一组静态方法

来为一组接口动态地生成代理类及其对象。

主要方法:

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler hanlder)

方法职责:为指定类加载器、一组接口及调用处理器生成动态代理类实例

参数:

loader:类加载器,一般传递真实对象的类加载器

interfaces:代理类需要实现的接口

hanlder:代理对象如何做增强:

返回:创建的代理对象

2java.lang.reflect.InvocationHandler 接口:

public Object invoke(Object proxy, Method method, Object[] args)

方法职责:负责集中处理动态代理类上的所有方法调用

参数:

proxy :生成的代理对象

method :当前调用的真实方法对象

args :当前调用方法的实参

返回: 真实方法的返回结果

以上是关于设计模式之代理模式的主要内容,如果未能解决你的问题,请参考以下文章

Spring之代理模式

#yyds干货盘点# 设计模式之代理模式:动态代理

设计模式之代理模式(Proxy)详解及代码示例

代理模式之静态代理实现代码

设计模式之代理模式

设计模式之代理模式