设计模式-代理模式

2017-08-11  本文已影响31人  KevinLive
代理模式 UML

下面是代理模式的一个简单实现:

Subject 类:

interface Subject {
    void request();
}

RealSubject 类:

class RealSubject implements Subject {
    @Override
    public void request() {
        LogUtils.i("我是真实对象");
    }
}

Proxy 类:

public class Proxy implements Subject {

    private RealSubject mRealSubject;

    public Proxy() {
        mRealSubject = new RealSubject();
    }
    
    @Override
    public void request() {
        LogUtils.i("调用真实对象前");
        mRealSubject.request();
        LogUtils.i("调用真实对象后");
    }
}

猛的一看和 装饰模式 非常的相似,装饰模式中的具体组件类(ConcreteComponent)和装饰类(Decorator)都实现同一个接口,代理模式中的抽象类(Subject)和代理类(Proxy)也是实现同一个接口,装饰类(Decorator)和代理类(Proxy)都是在真实对象的方法前面或者后面添加方法,但实际上,这两个模式还是又本质上的区别,装饰模式用于给一个对象动态添加方法,而代理模式用于控制一个对象的访问,隐藏对象的具体信息,代理模式中代理对象和真实对象间的关系在编译器就已经确定,而装饰模式是通过构造器传递,运行期才能确定,下面是 装饰类(Decorator) 的部分代码,对比 代理类(Proxy) 的代理就很清晰了

public class Decorator extends Component {

    private Component component;

    // 通过构造器传递对象
    public Decorator(Component component) {
        this.component = component;
    }
}

看完代理模式和装饰模式的区别,再来了解一下代理模式中的动态代理,上面是静态代理的例子,代理对象在编译期就已经存在;而动态代理不同于静态代理,动态代理通过反射机制在运行期动态生成代理对象,Java 中提供了一个 InvocationHandler 接口实现动态代理,下面是示例代码:

DynamicProxy 类:

public class DynamicProxy implements InvocationHandler {

    private Subject subject;

    public DynamicProxy(Subject subject) {
        this.subject = subject;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        LogUtils.i("方法调用前");
        Object invoke = method.invoke(subject, args);
        LogUtils.i("方法调用后");
        return invoke;
    }
}

静态代理 Client 类:

Proxy proxy = new Proxy();
proxy.request();

动态代理 Client 类:

Subject realSubject = new RealSubject();
DynamicProxy dynamicProxy = new DynamicProxy(realSubject);
Subject subject = (Subject)java.lang.reflect.Proxy.newProxyInstance(RealSubject.class.getClassLoader(), RealSubject.class.getInterfaces(),dynamicProxy);
subject.request();

优点

缺点

适用场景

上一篇 下一篇

猜你喜欢

热点阅读