代理设计模式以及其与装饰模式的区别

文章目录一、代理设计模式组成分类静态代理UML结构图静态代理模式示例静态代理的局限性动态代理动态代理UML结构图Additional Thinking二、装饰设计模式三、二者异同一、代理设计模式组成代理模式包含如下角色:Subject:抽象角色。通过接口或抽象类声明真实角色实现的业务方法。Proxy:代理角色。实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并...
摘要由CSDN通过智能技术生成

一、代理设计模式

组成

代理模式包含如下角色:

  • Subject:抽象角色。通过接口或抽象类声明真实角色实现的业务方法。
  • Proxy:代理角色。实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
  • RealSubject:真实角色。实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。

分类

代理可分为静态代理和动态代理,静态代理需要自己按照上面的UML类图来实现,并且在是在编译时就已经确定了代理,而Java提供了动态代理的方式,在反射包下面的DynamicProxy中,可以通过Proxy来运行时完成动态代理。

静态代理UML结构图

图1-1 代理设计模式

静态代理模式示例

首先创建抽象角色:

/*
* 抽象主题角色
* 为真实主题角色以及代理主题角色统一接口
* */
public interface Subject {
   
    void doSomething();
}

然后创建真实角色并实现抽象角色接口

/*
* 真实角色
* 实现了抽线角色接口
* */
public class RealSubject implements Subject,SubjectAnother {
   
    @Override
    public void doSomething() {
   
        System.out.println("RealSubject doSomething.");
    }
}

其次再创建代理角色,同样也实现抽象角色接口,并且代理角色持有真实角色

/*
* 代理角色
* */
public class Proxy implements Subject {
   
    /*
    * 持有一个真实角色的引用
    * */
    private Subject realSubject;

    public Proxy(Subject realSubject){
   
        this.realSubject = realSubject;
    }

    @Override
    public void doSomething() {
   
        // 在真实角色接口前附加职责
        System.out.println("Before realSubject.doSomething().");
        realSubject.doSomething();  // 调用真实角色的相应接口
        System.out.println("After realSubject.doSomething().");
    }
}

最后让我们测试静态代理的效果:

public class Main {
   
    public static void main(String[] args) {
   
        // 创建真实角色对象
        Subject realSubject = new RealSubject();
        // 用代理对象代理真实角色对象
        Subject proxySubject = new Proxy(realSubject);
        // 调用抽象角色定义的接口
        proxySubject.doSomething();
    }
}

// 输出结果为:
Before realSubject.doSomething().
RealSubject doSomething.
After realSubject.doSomething().

静态代理的局限性

  • 重复性。需要代理的接口越多就要去重复生成一些模板化的代码,不仅麻烦而且不易维护。
  • 脆弱性。一旦接口的定义修改,实现了该接口的真实角色以及代理角色的定义也要修改。

动态代理

JVM可以在运行器件动态生成类字节码(名字为$Proxy0),这种动态生成的类通常用来作为代理类,即动态代理类。JVM生成的动态代理类必须实现一个或多个接口,所以JVM生成的动态类只能用作具有相同接口的目标类的代理,如果要为一个没有实现接口的类生成动态代理类,可以使用CGLIB(实际上这也是SPRING框架除了JDK Proxy之外采用的另外一种生成代理类的方法),这里不对CGLIB作具体介绍。

动态代理UML结构图

图1-2 动态代理示意图
Java动态代理运用示例(就用刚才静态代理定义的接口以及真实角色):
首先自定义调用处理器(对代理对象的方法的调用最终都会被委派到自定义调用处理器上):

/*
* 自定义调用处理器,必须实现InvocationHandler接口
* */
public class InvocationHandlerImp implements InvocationHandler {
   
    // 被代理对象
    private Object object;

    public InvocationHandlerImp(Object object){
   
        this
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值