代理模式

本文通过实例详细比较了代理模式中的静态代理与动态代理的区别。静态代理需要为每个被代理对象的方法手动实现代理逻辑,而动态代理可以利用反射机制在运行时动态创建代理对象,更加灵活。

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

代理模式中有静态代理和动态代理之分,两者有何不同呢,用以下例子说明:

 

// 定义接口

public interface IShape {

       public void calc();

}

 

// 实现类

public class Circle implements IShape {

       public void calc() {

              System.out.println("calc : circle");

       }  

}

   

// 静态代理类

class StaticProxy implements IShape{

       private IShape shape = null;

       public StaticProxy(IShape shape) {

              this.shape = shape;

       }

       public void calc() {

              before();

              shape.calc();

              after();

       }

      

       public void before() {

              System.out.println("before");

       }

      

       public void after() {

              System.out.println("after");

       }

}

 

// 客户端类

public class TestStaticProxy {

       public static void main(String[] args) {

              new TestStaticProxy().doit();

       }

       public void doit() {

              StaticProxy sp = new StaticProxy(new Circle());

              sp.calc();

       }

}

 

运行客户端类,输出如下:

before

calc : circle

after

 

若在接口 IShape 中添加新方法,如

public interface IShape {

       ……

       public void transform();

}

 

则实现类也将添加 transform() 方法的实现

public class Circle implements IShape {

……

       public void transform() {

              System.out.println("Circle->Triangle");

       }

}

 

此时若客户端类调用transform()新方法

sp = new StaticProxy( new Circle() );

sp.transform();

则必须去修改 StaticProxy 类,如下:

class StaticProxy implements IShape{

       ……

public void transform() {

              System.out.println("before");

              shape.transform();

              System.out.println("after");

       }

}

 

若使用动态代理,情况就不同了,如下:

public class TestDynamicProxy {

       public static void main(String[] args) {

              IShape s = new Circle();      

              // 运行时动态创建代理类

              Class<?> clazz = Proxy.getProxyClass(IShape.class.getClassLoader(), new Class[]{IShape.class});

              try{

                     Constructor<?> constructor = clazz.getConstructor(new Class[]{InvocationHandler.class});

                     // 实例化一个代理对象

                     IShape shape = (IShape)constructor.newInstance(new Handler(new Circle()));

                     shape.calc();

                     // 调用新方法

         shape.transform();

              }catch(Exception e) {

                     e.printStackTrace();

              }

       }

}

 

class Handler implements InvocationHandler {

       private IShape shape = null;

       public Handler(IShape shape) {

              this.shape = shape;

       }

       public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

              System.out.println("before");

              Object result = method.invoke(shape, args);

              System.out.println("after");

              return result;

       }

}

 

可见,当在客户端类中调用接口 IShape 中添加的新方法时,可以在客户端类中直接调用,而不影响到其他代码,若使用静态代理,则必须在修改静态代理类后方可在客户端调用

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值