【设计模式】代理模式

这就是一个代理模式,让王工改需求,需要联系李总,李总再把工作安排给王工,最终完成了同样的目的,但是有个了中间人。

 

同样在Java里的代理模式,也这个道理,客户端不直接访问实际的对象,而是通过中间的代理对象来访问实际对象。

代理模式分为静态代理和动态代理

 

静态代理

代理和被代理对象在代理之前是确定的。都实现了相同的接口或继承相同的抽象类。举例:

创建IUser接口

/**
 * 用户接口
 */
public interface IUser {

    void login();
} 

目标对象User:

/**
 * 实现用户登录,目标对象
 */
public class User implements IUser {
    @Override
    public void login() {
        System.out.println("用户登录中.....");
    }
}

代理对象UserProxy

/**
 * 代理对象
 */
public class UserProxy implements IUser {

    private IUser target;

    public UserProxy(IUser target) {
        this.target = target;
    }

    @Override
    public void login() {
        System.out.println("用户开始登录");
        target.login();
        System.out.println("用户结束登录");
    }
}
 

 

测试Run.java

/**
 * 测试类
 */
public class Run {
    public static void main(String[] args) {

        //目标对象
        User target = new User();

        //代理对象,同时把目标对象传给代理对象
        UserProxy userProxy = new UserProxy(target);
        userProxy.login();

    }
}

运行结果:

用户开始登录
用户登录中.....
用户结束登录

 

总结:

1.静态代理可以代理实现任意接口的目标对象,通用性强。

2.接口有修改,目标对象和代理对象都要进行修改,增加了维护难度。

3.代理对象对应着一个目标对象,每个目标对象实现了部分接口,如果目标对象很多,那么静态代理对象也变得臃肿起来。

为了解决2,3问题,引入动态代理。

 

动态代理

这里介绍使用JDK的代理方式,同样可以代理实现接口的类。

步骤如下:

1.编写一个目标类的接口。

2.实现接口的目标类。

3.创建一个动态代理类,实现InvocationHandler接口,重写invoke方法。

举例:步骤1,2使用静态代理的IUser接口和User目标类。

创建一个动态代理类:

/**
 * 动态代理类
 */
public class DynamicProxy implements InvocationHandler {
    private Object target;

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

    /**
     * proxy    被代理的对象
     * method   被代理对象的方法
     * args     方法的参数
     * return   Object方法的返回值
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("开始登录");
        //执行目标类方法
        Object result = method.invoke(target, args);
        System.out.println("结束登录");
        return result;
    }
}
 

 

测试类:Run2.java

/**
 * 测试类
 */
public class Run2 {

    public static void main(String[] args) {

        //目标对象
        User target = new User();

        //代理对象,同时把目标对象传给代理对象
        DynamicProxy dynamicProxy = new DynamicProxy(target);

        //给目标生产代理对象
        /**
         * loader      类加载器
         * interfaces  实现接口
         * h           InvocationHandle
         */
        IUser iUser = (IUser) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), dynamicProxy);
        iUser.login();
    }
}

运行结果:

用户开始登录
用户登录中.....
用户结束登录

posted @ 2019-04-02 11:18  蜗牛201  阅读(114)  评论(0编辑  收藏  举报