设计模式-10【代理模式--Proxy】

代理模式

在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。为其他对象提供一种代理以控制对这个对象的访问。

主要解决:在直接访问对象时带来的问题,比如说:要访问的对象在远程的机器上。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层。

关键代码:增加中间层,实现与被代理类组合。

优点:

 1、职责清晰。 2、高扩展性。 3、智能化。

缺点:

1、由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。

2、实现代理模式需要额外的工作,有些代理模式的实现非常复杂。

注意事项: 

1、和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。

2、和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。


代码实现

首先创建公共接口和被代理对象实体

//公共接口
public interface Rent {
    void renting();
}
​
//被代理对象
public class Corey implements Rent {
    //这是被代理对象!(房主)
    @Override
    public void renting() {
        System.out.println("Corey有房出租");
    }
}

1.静态代理 

 代理对象实例

//代理对象(中介)
public class StaticProxyRent implements Rent {
    private Rent rent;

    public StaticProxyRent(Rent rent){
        this.rent = rent;
    }

    @Override
    public void renting() {
        System.out.println("向房客出租房屋");
        this.rent.renting();
        System.out.println("完成售后服务");
    }
}

测试

public class Main {
    public static void main(String[] args) {
        Rent rent = new Corey();
        StaticProxyRent staticProxyRent = new StaticProxyRent(rent);
        staticProxyRent.renting();
    }
}

 2.动态代理 

JDK动态代理

newProxyInstance:生成代理对象Proxy

asm:通过操作字节码,生成Proxy$0文件

XXXX.getClassLoader():负责把磁盘上的.class文件加载到JVM内存中

XXXX.getInterfaces():获得这个对象所实现的所有接口

InvocationHandler():自行编译需要的代理功能

invoke(Object proxy, Method method, Object[] args):proxy是代理对象本身,method是被代理的方法,args是代理方法的参数。

 代理对象实例

//代理对象(中介)
//动态生成代理对象的工厂
public class JdkProxyFactory {
    public static void before(){
        System.out.println("带领房客看房...签租房协议");
    }
    public static void after(){
        System.out.println("售后服务");
    }

    //动态生成代理对象
    public static Object getProxyBean(Object target){
        Class clazz = target.getClass();
        //在JDK中动态生成代理对象的方法
        return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), new InvocationHandler() {
            //动态生成代理对象的方法
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                before();
                Object obj =  method.invoke(target,args);
                after();
                return obj;
            }
        });
    }
}

测试

public class Main {
    public static void main(String[] args) {
        Rent jdkProxyRent = new Corey();
        Rent jdkProxyRent1 =(Rent)JdkProxyFactory.getProxyBean(jdkProxyRent);
        jdkProxyRent1.renting();
    }
}

Cglib动态代理

enhancer  成为被代理类的子类,假如类为final则不能使用Cglib实现代理。

代理对象实例

public class CglibProxyBeanFactory {
    public static Object getProxyBean(Rent rent){
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(rent.getClass());
        enhancer.setCallback(new MethodInterceptor() {

            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                System.out.println("带领客户看房,签订租房协议");
                Object obj = method.invoke(rent,objects);
                System.out.println("售后服务");
                return obj;
            }
        });
        return enhancer.create();
    }
}

测试

public class Main {
    public static void main(String[] args) {
        Rent rent = new Corey();
        Rent rent1 = (Rent) CglibProxyBeanFactory.getProxyBean(rent);
        rent1.renting();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值