java设计模式学习笔记--代理模式

1. 什么是代理模式

代理模式是对象的结构模式。代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。

2.代理模式的结构

代理模式有两种:静态代理和动态代理。
先来看一下静态代理:

2.1 静态代理:

在代理模式中,有三个角色:

抽象对象角色:声明了目标对象和代理对象的共同接口,这样一来在任何可以使用目标对象的地方都可以使用代理对象。

目标对象角色:定义了代理对象所代表的目标对象。

代理对象角色:代理对象内部含有目标对象的引用,从而可以在任何时候操作目标对象;代理对象提供一个与目标对象相同的接口,以便可以在任何时候替代目标对象。代理对象通常在客户端调用传递给目标对象之前或之后,执行某个操作,而不是单纯地将调用传递给目标对象。

例子如下:

/**
 * 抽象对象角色
 */
public abstract class AbstractObject {
    public abstract void operation();
}
/**
 * 目标对象角色
 */
public class RealObject extends AbstractObject{
    @Override
    public void operation() {
        System.out.println("do something");
    }
}
/**
 * 代理对象角色
 */
public class ProxyObject extends AbstractObject{

    private AbstractObject ao;

    public ProxyObject(AbstractObject ao) {
        this.ao = ao;
    }

    @Override
    public void operation() {
        System.out.println("before..........");
        ao.operation();
        System.out.println("after...........");
    }
}
public class Client {
    public static void main(String[] args){
        AbstractObject ao = new RealObject();
        ProxyObject po = new ProxyObject(ao);
        po.operation();
    }
}

运行结果如下:
before..........
do something
after...........

静态代理很简单,看一下就可以看懂。
静态代理的特点:在程序运行之前。代理类就已经生成了。
缺点:
1、代理对象的一个接口只服务于一种类型的对象,如果要代理的方法很多,势必要为每一种方法都进行代理,静态代理在程序规模稍大时就无法胜任了。
2、如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。

所以,当出现需要代理很多类时,我们就可以使用动态代理。

2.2 动态代理

先来看代码:

首先还是定义一个动态代理接口:

public interface TestInterface {
    void Sing();
}

写一个实现类:

public class TestClass implements TestInterface{

    @Override
    public void Sing() {
        System.out.println("sing a song");
    }
}

创建动态代理类,这里必须实现InvocationHandler接口,并实现接口中的invoke()方法。

public class DynamicProxy implements InvocationHandler{

    private Object object;

    public Object newInstance(Object object){
        this.object = object;
        //生成一个动态代理类
        return Proxy.newProxyInstance(object.getClass().getClassLoader(),object.getClass().getInterfaces(),this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before sing......... ");
        Object ob = method.invoke(object,args);
        System.out.println("after sing.......... ");
        return ob;
    }
}
public class Client {
    public static void main(String[] args){
        TestInterface ti = new TestClass();
        DynamicProxy dp = new DynamicProxy();
        TestInterface t = (TestInterface) dp.newInstance(ti);
        t.Sing();
    }
}


输出:
before sing......... 
sing a song
after sing.......... 

1、之所以成为动态代理,是因为只在运行时才将类创建出来,代码开始执行时,还没有Proxy类,他是根据传入的接口集创建的。
2、InvocationHandler是一个帮助proxy的接口,proxy会把调用转发给他处理。proxy本身是利用Proxy.newProxyInstance()方法(该方法传入的只能是接口数组,里面不能有类),在运行时动态创建的。

动态代理优点:
动态代理模式通过使用反射,可以在运行期决定加载哪个类,避免了一个类对应一个代理的问题。

你可能感兴趣的:(java设计模式,java,java设计模式)