代理模式

代理模式

一、相关概念:

Head First设计模式:

代理模式为另一个对象提供一个替身或占位符以控制对这个对象的访问

主要作用:控制对象访问
- 扩展目标对象的功能:例如演员(目标对象),有演戏的功能,找一个经纪人(代理),会额外提供收费的功能,实际上是代理的功能,而不是演员的功能。
- 限制目标对象的功能:例如经纪人对收费不满意,只让演员演一场戏,对演员的功能进行了部分限制。

二、静态代理:

编译时期就已经存在,一般首先需要定义接口,而被代理的对象和代理对象一起实现相同的接口。
1、接口定义:

 public interface Play {
    //唱歌
    void sing(int count);
    //演出
    void show();
}

2、演员(被代理对象):

public class Actor implements Play {
    @Override
    public void sing(int count) {
        System.out.print("唱了" + count + "首歌");
    }

    @Override
    public void show() {
        System.out.print("进行演出");
    }
}

3、经纪人(代理对象):

public class Agent implements Play {

    private Play player;
    private long money;

    public void setMoney(long money){
        this.money = money;
    }

    /**
     * @param player
     * @param money 收费
     */
    public Agent(Play player, long money) {
        this.player = player;
        this.money = money;
    }

    @Override
    public void sing(int count) {
        player.sing(count);
    }

    @Override
    public void show() {
        if (money > 100) {
            player.show();
        } else {
            System.out.println("baibai...");
        }
    }
}

4、测试:

public class PlayTest {
    public static void main(String[] args){
        Actor actor = new Actor();
        Agent agent = new Agent(actor, 50);
        agent.sing(2);
        agent.show();
        agent.setMoney(200);
        agent.show();
    }
}

结果:
这里写图片描述
代理对象通过自身的逻辑处理对目标对象的功能进行控制。

三、动态代理:

动态一般指的是在运行时的状态,是相对编译时的静态来区分,就是在运行时生成一个代理对象帮我们做一些逻辑处理。主要使用反射技术获得类的加载器并且创建实例。
1、如何生成动态代理类:
java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力
(1)Proxy类:
Proxy类是专门完成代理的操作类,可以通过此类为一个或多个接口动态地生成实现类,此类提供了如下的操作方法:

 public static Object newProxyInstance(ClassLoader loader,
                                      Class<?>[] interfaces,
                                      InvocationHandler h)
    throws IllegalArgumentException{
    ...
 }

参数说明:
- ClassLoader loader:类加载器
- Class<>[] interfaces:所有的接口
- InvocationHandler h:实现InvocationHandler接口的子类

(2)InvocationHandler接口:

public interface InvocationHandler {
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable;
}

参数说明:
- Object proxy:被代理的对象
- Object[] args:要调用的方法
- Object[] args:方法调用所需要的参数

2、动态代理demo:
(1)动态代理类:

public class ActorProxy implements InvocationHandler {
    private Play player;
    public ActorProxy(Play player){
        this.player = player;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if ("show".equals(method.getName())){
            System.out.println("代理处理show....");
            return method.invoke(player, null);
        }else if ("sing".equals(method.getName())){
            System.out.println("代理处理sing....");
            return method.invoke(player, 2);
        }
        return null;
    }
}

代理类实现InvocationHandler接口,在invoke方法中对player(被代理对象)做相应的逻辑处理。
(2)测试:

public class ProxyTest {

    public static void main(String[] args) {
        Play actor = new Actor();
        Play proxy = (Play) Proxy.newProxyInstance(actor.getClass().getClassLoader()
                , actor.getClass().getInterfaces(), new ActorProxy(actor));
        proxy.show();
        proxy.sing(3);
    }
}

通过调用Proxy.newProxyInstance方法生成代理对象。
结果:
这里写图片描述
动态代理可以在运行时动态创建一个类,实现一个或多个接口,可以在不修改原有类的基础上动态为通过该类获取的对象添加方法、修改行为。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值