代理模式的理解

代理模式的理解

**代理模式:指为目标对象提供一个代理对象,外部对目标对象的访问,通过代理委托进行已达到控制访问的目的。
自己的理解:代理类再次封装目标类,代理类依赖于目标类(即将目标对象作为代理类的一个成员对象),同样实现相同的接口,达到增强方法(增加额外的操作)或者控制访问的目的。
具体实现看下面:

静态代理**

实现如下:

package myInterfaces;

public interface Speakable {
    public void speak( String message);
}
package myObject;

import myInterfaces.Speakable;

public class Dog implements Speakable {
    @Override
    public void speak(String message) {
        System.out.println("旺旺:"+message);
    }
}

package myObject;

import myInterfaces.Speakable;

public class Person implements Speakable {
    @Override
    public void speak(String message) {
        System.out.println("Hello:"+message);
    }
}

package myProxy;

import myInterfaces.Speakable;
import myObject.Dog;

public class DogProxy implements Speakable {
     private Dog dog;
     public DogProxy(Dog dog){
         this.dog=dog;
     }

    @Override
    public void speak(String message) {
         this.dog.speak(message);
        System.out.println("运行时间:"+System.currentTimeMillis());
    }
}

package myProxy;

import myInterfaces.Speakable;
import myObject.Person;

public class PersonProxy implements Speakable {/************实现相同的接口**********/
    private Person person;/******************,再次封装,将目标对象作为一个成员变量*********/
    public PersonProxy(Person person){
        this.person=person;
    }
    @Override
    public void speak(String message) {
        this.person.speak(message);
        System.out.println("运行时间:"+System.currentTimeMillis());/****额外的操作,,,增强方法******/
    }
}

项目结构:
在这里插入图片描述

从上图可以看出静态代理的优点:
1)实现简单
2)容易理解
缺点:
1)实现起来类太多了。要为专门一个目标类写一个代理类,如一个Dog目标类,要写DogProxy,Person目标类,要写一个PersonProxy,如果目标类太多的话,代理类也需要同样多的代理类。类的数量成倍增加。
2)拓展性太差,可维护性差。如果考虑要为Speakble接口增加一个方法。那所有的目标类,所有的实现类都必须要重新修改,拓展性差,可维护性差。

在这里插入图片描述
全部报红,即全部的目标类和代理类全部需要修改
在这里插入图片描述

动态代理

动态代理demo如下

目标接口

package myInterfaces;

//目标接口
public interface Speakable {
    public String  speak();
}

实现类1

package myObject;

import myInterfaces.Speakable;
//目标类
public class Dog implements Speakable {
    @Override
    public String speak() {
        return "旺旺";
    }
}

实现类2

package myObject;

import myInterfaces.Speakable;

//目标类
public class Person implements Speakable {
    @Override
    public String  speak() {
       return "Hello";
    }
}

调用处理器

package myhandler;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;


//调用处理器
public class MyHandler implements InvocationHandler {//实现固定接口
    Object target;//目标对象

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

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      Object res=null;
      res=method.invoke(target, args);//调用目标方法

      if(res!=null){
          System.out.println("新年快乐  "+(String)res);//方法增强
      }
     return res;
    }
}

main方法

package main;

import myInterfaces.Speakable;
import myObject.Dog;
import myObject.Person;
import myhandler.MyHandler;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class Main {
    public static void main(String[] args) {
        //目标对象
        Speakable dogspeak=new Dog();

        //传入调用处理器
        InvocationHandler doghandler=new MyHandler(dogspeak);

        //获取代理对象
         Speakable dogproxy =(Speakable)Proxy.newProxyInstance(dogspeak.getClass().getClassLoader(),
                dogspeak.getClass().getInterfaces(),
                doghandler);
         //调用方法
        dogproxy.speak();


        Speakable personspeak =new Person();
        InvocationHandler personhandler=new MyHandler(personspeak);
        Speakable personproxy=(Speakable) Proxy.newProxyInstance(personspeak.getClass().getClassLoader(),
                personspeak.getClass().getInterfaces(),
                personhandler);
        personproxy.speak();
    }
}

动态代理就是通过反射机制,让jdk动态生成代理对象,而不需要再像静态代理那样为每个目标对象写一个代理类。原先要在代理对象中写的方法,现在写到调用处理器中。
在debug模式下看一下执行过程,代理对象调用的方法,实际上是调用处理器中的invoke方法。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这里也可以看出调用处理器就是一个抽象的代理类。根据你在实现过程中传入的参数,就可以动态的生成一个你所需的代理类。

动态代理的实现步骤如下:

1.创建接口,定义目标类要完成的功能
2. 创建目标类实现接口
3. 创建InvocationHandler接口的实现类,在invoke方法中完成代理类的功能 (增强功能,或方法)
4.使用Proxy类的静态方法,创建代理对象。 并把返回值转为接口类型。

动态代理说得比较 好的一篇博客(转)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值