【BigHereo 9】-----设计模式之动态代理

本文深入浅出地介绍了代理模式中的动态代理概念,通过实例演示了静态代理与动态代理的区别,并探讨了代理模式的各种应用场景及其实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


 

【BigHereo 9】------设计模式之动态代理

 

 

【前言】

     所有的设计模式中,你知道实现起来那个最好给力吗?动态代理,当之无愧是所有设计模式中,等你用完之后是会有一种无比自豪感觉.今天小编就代理来领略一下什么是动态代理.

 

 

在了解动态代理之前,看看你能否回答下面几个问题:

   1,什么是代理?什么是代理模式

   2,什么是静态代理?什么是动态代理?

   3,代理模式有什么东西?

   4,代理模式有什么优缺点?

   5,代理模式能干什么? 怎么干?

   6,Proxy的应用场景和最佳实践?

   7,Proxy, Adapter(适配器),Decorator(装饰器)的对比?


 

【谋全局】

 

 

 

 

 下面我就用装饰模式的方法,一层一层的给您细细道来:


 

1,什么是代理,什么是代理模式?

     代理: 不是自己亲自做干某件事,找一个代理,但是事是同一件.例如,你想买盐,你叫你舍友给你带回来,这过程就是一个代理. 都是买盐,但不是你自己去买,而是你同事代你买的.

 

    代理模式: 什么是设计模式? 通俗的说,设计模式就是一种解决问题的思路,或方法. 代理模式就是用代理的方式来解决问题.



UML图:

          

 

 

简单的类图:

            



2,什么是静态代理?什么是动态代理?

   静态代理: 程序运行前就已经存在代理字节码,代理类和委托关系在运行前就已经确定了.

 

   动态代理: 运行前没有确定代理类和委托关系,运行接口才指定哪一个对象.

                     动态代理不需要实现接口,所以动态代理也叫: jdk代理.


 

3,代理模式有什么东西?

      通过上面的两个问题,我们可以总结出来,代理模式有两种: 静态代理和动态代理.


 

 

4,代理模式有什么优缺点?

            



 

5,代理模式能干什么? 怎么干?

   1,远程代理(Remote Proxy):

       物理位置不同

 

   2,虚拟(Virtual Proxy): 

      创建开销很大对象---例如图片加载,先加载一个图框; 算法很长先加载一部分.

 

   3,保护/安全(Protection Proxy): 

       控制原对象访问权限

 

   4,智能指引(Smart Reference)

        取代简单的指针,访问对象时执行一些附加操作.

 

  5,Copy-on-Write代理

       把复制(克隆)延迟到客户端真正需要是才执行.

 

 

6,Proxy的应用场景和最佳实践?

       




7,Proxy, Adapter(适配器),Decorator(装饰器)的对比?

     




【举个栗子】

 

 

 

 

 

共用接口: Moveable:

package proxy;

/**
 * Created by Daniel on 2017/8/23.
 */
public interface Moveable
{
    void move();
    //继承方式实现代理,写很多的继承,非常的麻烦
}
 


真实类: Tank1:

package proxy;
import java.util.Random;

/**
 * Created by Daniel on 2017/8/23.
 */
public class Tank1 implements Moveable{
    //代理实现方式,继承和聚合两中方式
    @Override
    public void move() {

        long start =System.currentTimeMillis();

        System.out.println("Tank1 Moving,,,,,");
        try {
            Thread.sleep(new Random().nextInt(10000));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        long end=System.currentTimeMillis();
        //想知道一共多长时间?
        System.out.println("time:"+ (start-end));

        //代理:知道日志
        //代理: 添加事务,让事务进行回滚
    }
}


 

代理类: Tank2Proxy:

package proxy;

/**
 * Created by Daniel on 2017/8/23.
 */
public class Tank2Proxy extends Tank1 {
    //方法一: 继承实现
    @Override
    public  void  move(){
        long start=System.currentTimeMillis();
        super.move();
        long end=System.currentTimeMillis();
        System.out.println("time"+(end-start));
    }
}
 


客户端: Client:

package proxy;

/**
 * Created by Daniel on 2017/8/23.
 */
public class Client {

   public  static void  main(String[] args){
       //继承方法实现记录
       oveable m=new Tank2Proxy();
       m.move();
     }
}

 

 

【代理中的继承和聚合】

   代理的实现有两种方式,继承和聚合,设计模式中一个非重要的原则就是: 多用集合少用继承.

 

   从我们这个代理模式也可以体现出来:

方法一: 继承实现代理:

package proxy;

/**
 * Created by Daniel on 2017/8/23.
 */
public class Tank2Proxy extends Tank1 {
    //方法一: 继承实现
    @Override
    public  void  move(){
        long start=System.currentTimeMillis();
        super.move();
        long end=System.currentTimeMillis();
        System.out.println("time"+(end-start));
    }
}


 

方法二: 聚合实现

package proxy;

/**
 * Created by Daniel on 2017/8/23.
 */
public class TankTimeProxy implements  Moveable{
    //方法二:聚合实现
    public TankTimeProxy(Moveable t) {
        super();
        this.t = t;
    }
    Moveable t;

    @Override
    public void move()  {
        long start=System.currentTimeMillis();
        System.out.println("startTime:"+start);
        t.move();
        long end=System.currentTimeMillis();
        System.out.println("endTime:"+end);
        System.out.print("time:"+(end-start));
    }
}


  

客户端代码:

package proxy;

/**
 * Created by Daniel on 2017/8/23.
 */
public class Client {

   public  static void  main(String[] args){
       //继承方法实现记录
       /*Moveable m=new Tank2Proxy();
       m.move();*/

       //================聚合方法实现===========================
       /*Tank1 t=new Tank1();
       //日志包着时间---先记录时间,再日志
       TankTimeProxy ttp =new TankTimeProxy(t);
       TankLogProxy tlp=new TankLogProxy(ttp);
       Moveable m=tlp;
       m.move();*/

       Tank1 t=new Tank1();
       //时间包着日志,先记录日志,才有时间
       TankLogProxy tlp=new TankLogProxy(t);
       TankTimeProxy ttp =new TankTimeProxy(tlp);
       Moveable m=ttp;
       m.move();
     }
}

 

 

【小结】

    1,从小到大,很有意思的一个大家都了解的例子就是:   猪八戒背媳妇,后来发现背上的高翠兰是孙悟空变得,这里孙悟空是代理类,主要是让高翠兰安全得到保护.

   

   2,为什么集合比继承好?

   (1)继承虽然简单,但相对于聚合来说,不安全,继承破坏封装的类.

      (2)用继承,基类改变了,派生类也会随之改变.

      (3)从基类继承而来的派生类是静态的,不可能在运行时间内发生改变,没有足够的灵活性.

 

 

 

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值