结构型模式之代理模式

2018-12-16  本文已影响4人  sunpy
优秀.jpg

什么是代理模式

代理模式顾名思义就是使用一个代理类来代替原对象,来进行一些操作。按照我的理解:就是原对象委托给代理对象来处理。

代理模式的种类

静态代理、JDK代理、Cglib代理

静态代理

结构:


Proxy.png

抽象主题角色、具体主题角色、代理主题角色

/** 抽象主题角色 */
interface Subject {
    public void buy();
}

/** 具体主题角色 */
class Purchaser implements Subject {

    @Override
    public void buy() {
        System.out.println("Purchaser买啤酒!");
    }
}

/** 代理主题角色 */
class ProxyPurchaser implements Subject {

    private Purchaser purchaser;
    
    public ProxyPurchaser(Purchaser purchaser) {
        this.purchaser = purchaser;
    }

    @Override
    public void buy() {
        System.out.println("ProxyPurchaser代理Purchaser");
        purchaser.buy();
    }
}

测试:

public class ProxyTest {

    public static void main(String[] args) {
        Subject proxyPurchaser = new ProxyPurchaser(new Purchaser());
        proxyPurchaser.buy();
    }
}

结果:

ProxyPurchaser代理Purchaser
Purchaser买啤酒!

优点:可以做到不修改目标对象功能的前提下,对目标对象实现了扩展,遵循了开闭原则。
缺点:由于静态代理其本身的特点,代理类和目标对象实现同一个接口,同时这也是一个缺点,如果目标对象需要增加更多,那么需要增加更多的代理类。同时接口也在增加更多,都需要维护,这样很麻烦。

JDK代理

public class ProxyTest {

    public static void main(String[] args) {
        ProxyUtil proxyUtil = new ProxyUtil(new Purchaser());
        Subject subject = (Subject) proxyUtil.getProxyInstance();
        subject.buy();
    }
}

/** 抽象主题角色 */
interface Subject {
    public void buy();
}

/** 具体主题角色 */
class Purchaser implements Subject {

    @Override
    public void buy() {
        System.out.println("Purchaser买啤酒!");
    }
}

/** 代理工具类 */
class ProxyUtil implements InvocationHandler {

    private Object obj;
    
    public ProxyUtil(Object obj) {
        this.obj = obj;
    }

    public Object getProxyInstance() {
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                obj.getClass().getInterfaces(), 
                this);
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        System.out.println("ProxyPurchaser代理Purchaser");
        return method.invoke(obj, args);
    }
}

Cglib代理

public class ProxyTest {

    public static void main(String[] args) {
        Subject subject = new CglibUtil().getProxyInstance(Purchaser.class);
        subject.buy();
    }
}

/** 抽象主题角色 */
interface Subject {
    public void buy();
}

/** 具体主题角色 */
class Purchaser implements Subject {

    @Override
    public void buy() {
        System.out.println("Purchaser买啤酒!");
    }
}

/** 代理工具类 */
class CglibUtil implements MethodInterceptor {

    @SuppressWarnings("unchecked")
    public <T> T getProxyInstance(Class<T> clazz) {
        return (T) Enhancer.create(clazz, this);
    }
    
    @Override
    public Object intercept(Object obj, Method method, Object[] args,
            MethodProxy proxy) throws Throwable {
        System.out.println("ProxyPurchaser代理Purchaser");
        return proxy.invokeSuper(obj, args);
    }
}

参数解析:
intercept方法参数:
Object obj:表示要进行增强的对象
Method method:表示拦截的方法
Object[] args:基本数据类型需要传入其包装类型
MethodProxy proxy:表示对方法的代理
而实际上Cglib可以更灵活的使用:cglib动态代理的使用

代理模式和装饰器模式的区别

装饰器模式仅仅就是给原定的功能上加上了一层额外的业务逻辑进行了封装。
代理模式是代理原对象,代理模式的主要目得是为了代理原对象去执行。

上一篇下一篇

猜你喜欢

热点阅读