设计模式---代理模式

静态代理

某个对象提供一个代理,代理角色固定,以控制对这个对象的访问。 代理类和委托类有共同的父类或父接口,这样在任何使用委托类对象的地方都可以用代理对象替代。代理类负责请求的预处理、过滤、将请求分派给委托类处理、以及委托类执行完请求后的后续处理。

在这里插入图片描述

举例子:小明现在想去追小红,但是他害羞不敢直接追,通过小代去追小红。这个时候,小明就是被代理类,小代就是代理类,因为小明要让小代去送公仔、送花、送巧克力,这些行为,小代肯定也是要有的,所以小明和小代是集成同一个接口。

最求者和代理者的公共行为:

/**
 * 最求者要执行的方法
 * 代理类和被代理类都要集成同一个接口,这样被代理类执行方法的时候,代理类执行同样的方法,对被代理类要执行的方法前后进行加强。
 */
public interface GiveGirl {
    void giveDolls(); // 送公仔
    void giveFlowers(); // 送花
    void givechocolate(); // 送巧可力
}

被追求的人,也就是小红

public class SchoolGril {
    private String name;

    public SchoolGril(String name) {
        this.name = name;
    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

追求的人,也就是小明,也就是实现了具体的行为。

/**
 * 追求者,也就是被代理类,通过被人去追求女朋友
 */
public class Pursuit implements GiveGirl {
    SchoolGril schoolGril;

    public Pursuit(SchoolGril schoolGril) {
        this.schoolGril = schoolGril;
    }


    @Override
    public void giveDolls() {
        System.out.println(schoolGril.getName() + "," + "送你洋娃娃" );
    }

    @Override
    public void giveFlowers() {
        System.out.println(schoolGril.getName() + "," + "送你鲜花" );
    }

    @Override
    public void givechocolate() {
        System.out.println(schoolGril.getName() + "," + "送你巧克力" );
    }
}

静态代理类,也就是小代,也实现了行为接口,毕竟你是代理人,不能完全执行被代理人小明的工作怎么行呢。

public class StaticProxy implements GiveGirl {

    //代理的对象,说明是代理,那肯定要有被代理人了
    Pursuit pursuit;

    //传入代理需要追求者
    public StaticProxy(SchoolGril schoolGril) {
        pursuit = new Pursuit(schoolGril);
    }

    @Override
    public void giveDolls() {
        //被代理对象执行前做处理的地方

        pursuit.giveDolls();

        //被代理对象执行后做处理的地方
    }

    @Override
    public void giveFlowers() {
        //被代理对象执行前做处理的地方

        pursuit.giveFlowers();

        //被代理对象执行后做处理的地方
    }

    @Override
    public void givechocolate() {
        //被代理对象执行前做处理的地方

        pursuit.givechocolate();

        //被代理对象执行后做处理的地方
    }
}

测试类

public class TestStaticProxy {
    public static void main(String[] args) {
        SchoolGril schoolGril = new SchoolGril("lisa");
        StaticProxy staticProxy = new StaticProxy(schoolGril);

        //代理执行的方法,将被代理对象隐藏起来
        staticProxy.giveDolls();
        staticProxy.giveFlowers();
        staticProxy.givechocolate();
    }
}

动态代理

相比于静态代理,动态代理在创建代理对象上更加的灵活,动态代理类的字节码在程序运行时,由Java反射机制动态产生。它会根据需要,通过反射机制在程序运行期,动态的为目标对象创建代理对象,无需程序员手动编写它的源代码。动态代理不仅简化了编程工作,而且提高了软件系统的可扩展性,因为反射机制可以生成任意类型的动态代理类。代理的行为可以代理多个方法,即满足生产需要的同时又达到代码通用的目的。

动态代理的两种实现方式:

  1. JDK 动态代理

  2. CGLIB动态代理

代理类也就是小代,需要实现InvocationHandler接口

/**
 * 代理类
 */
public class DynamicProxy implements InvocationHandler {

    // 目标对象的类型不固定,创建时动态生成
    private Object target;

    public DynamicProxy(Object target) {
        this.target = target;
    }

    /**
     *  1、调用目标对象的方法(返回Object)
     *  2、增强目标对象的行为
     * @param proxy 调用该方法的代理实例
     * @param method  目标对象的方法
     * @param args  目标对象的方法形参
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 增强行为
        System.out.println("==============方法前执行");

        // 调用目标对象的方法(返回Object)
        Object result = method.invoke(target,args);

        // 增强行为
        System.out.println("方法后执行==============");
        return null;
    }

    /**
     * 得到代理对象
     * public static Object newProxyInstance(ClassLoader loader,
     *                                       Class<?>[] interfaces,
     *                                       InvocationHandler h)
     *      loader:类加载器
     *      interfaces:接口数组
     *      h:InvocationHandler接口 (传入InvocationHandler接口的实现类)
     *
     *
     * @return
     */
    public Object getProxy() {
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }
}

Proxy.newProxyInstance()是创建代理对象的方法。

测试类

public class TestDynamicProxy {
    public static void main(String[] args) {
        SchoolGril schoolGril = new SchoolGril("Mary");
        Pursuit pursuit = new Pursuit(schoolGril);
		
		//传入要代理的对象,小明
        DynamicProxy dynamicProxy = new DynamicProxy(pursuit);
       	//获取代理的对象,小代
        GiveGirl proxy = (GiveGirl) dynamicProxy.getProxy();
        proxy.giveDolls();

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值