代理设计模式

一、定义

为其他对象提供一种代理,以控制对该对象的访问。

二、简图
这里写图片描述
三、分类

代理模式分静态代理和动态代理两种模式

四、代码实例

需求:原告通过律师向法院进行申诉

分析:

1、静态代理实现
A:创建申诉接口IAppeal

/**
 * 申诉接口
 * @author petergee
 * @date 2018/3/15
 */

public interface IAppeal {
    //申诉方法
    void appeal();
}

B:创建原告类实现接口

/**
 * 原告类
 *
 * @author petergee
 * @date 2018/3/15
 */

public class Plaintiff implements IAppeal {
    private String mName;

    public Plaintiff(String name) {
        this.mName = name;
    }

    @Override
    public void appeal() {
        System.out.println("I am " + mName + ",i wanna appeal");
    }
}

C:创建律师类作为代理,同时实现申诉接口,并代理原告申诉

/**
 * 律师类
 *
 * @author petergee
 * @date 2018/3/15
 */

public class Lawyer implements IAppeal {

    private Plaintiff mPlaintiff;

    public Lawyer(Plaintiff plaintiff) {
        this.mPlaintiff = plaintiff;
    }

    @Override
    public void appeal() {
        mPlaintiff.appeal();
    }
}

D:测试类

/**
 * 测试类
 * @author petergee
 * @date 2018/3/15
 */

public class StaticProxyClassTest {
    public static void main(String[] args) {
        //创建原告实例
        Plaintiff plaintiff = new Plaintiff("ThreeZhang");
        Lawyer lawyer = new Lawyer(plaintiff);
        lawyer.appeal();


    }
}

E:结果
这里写图片描述

F:分析
优点:
通过代理类可以对被代理类进行封装,实现被代理类需求
缺点:
被代理类和代理类都要实现同一个接口,当有多个被代理类时需要实现多个接口,会导致代理类变得复杂

2、动态代理实现

由于JDK中帮我们提供了生成动态代理的API

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

下面使用该API实现上述需求
A:创建动态代理申诉接口DynamicIAppeal

/**
 * 申诉接口
 * @author petergee
 * @date 2018/3/15
 */

public interface DynamicIAppeal {
    //申诉方法
    void appeal();
}

B:创建原告类实现DynamicIAppeal

/**
 * 动态代理原告类
 *
 * @author petergee
 * @date 2018/3/15
 */

public class DynamicPlaintiff implements DynamicIAppeal {
    private String mName;
    public DynamicPlaintiff(String name){
        this.mName=name;
    }

    @Override
    public void appeal() {
        System.out.println("i am "+mName+" i wanna appeal");
    }
}

C:创建动态代理律师类使用Proxy.newProxyInstance方法获取被代理的类实例

package net.petergee.designmodedemo.designmode.proxy.dynamicProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 动态代理律师类
 *
 * @author petergee
 * @date 2018/3/15
 */

public class DynamicLawyer {

    private Object mObject;

    /**
     * Object类型对象通过构造传递 ,更加灵活
     * @param o
     */
    public DynamicLawyer(Object o) {
        this.mObject = o;
    }

    /**
     * 获取动态代理对象
     * 参数:classLoader 、interface、InvocationHandler
     */
    public Object getDynamicProxy() {
        return Proxy.newProxyInstance(mObject.getClass().getClassLoader(), mObject.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object value = method.invoke(mObject, args);
                return value;
            }
        });
    }

}

可见动态代理构造方法中并没有将对象类型固定,而是提供了Object类型,可以代理多种类型被代理类
,动态代理DynamicLawyer中没有 实现DynamicIAppeal接口而是通过JDK提供的方法来获取被代理类对象,相比静态代理更加灵活

D:测试类

package net.petergee.designmodedemo.designmode.proxy.dynamicProxy;

/**动态代理测试类
 * @author petergee
 * @date 2018/3/15
 */

public class DynamicProxyTest {
    public static void main(String[] args) {
        DynamicIAppeal plaintiff = new DynamicPlaintiff("FourLi");
        DynamicIAppeal proxy = (DynamicIAppeal) new DynamicLawyer(plaintiff).getDynamicProxy();
        proxy.appeal();

    }
}

E:结果
这里写图片描述

F:分析
(1)、动态代理代理类不必实现被代理类接口,可以使用JDK提供的动态代理API获取被代理对象
(2)、被代理类一定要实现一个接口,否则不起作用

代码Demo仓库地址:https://github.com/PeterGee/DesignModeDemo
参考:https://www.cnblogs.com/cenyu/p/6289209.html)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值