从代购到代理模式

随着生活水平的提高,人们对物质的需求也随之提高,但是有些东西是自己周遭还没有的,只能去别的地方购买,但是出于时间和成本的考虑,人们一般不会选择为了购买东西而专门来一次说走就走的行程。这个时候,代购就出现了。

当然我们不是为了来讲代购的,而是来总结一种在系统开发中用到的一种设计模式---代理模式。代理模式和代购的作用如出一辙。只要你知道代购是干嘛的,你就知道代理模式是干嘛的了。

在 Java 中,代理模式分为动态代理和静态代理。

下面是介绍静态代理的案例:

public interface Subject {  //创建一个抽象接口,声明需要让代购做的事情
    void buy();
}
public class RealSubject implements Subject{    //创建真实对象类,实现抽象接口
    @Override
    public void buy() {
        System.out.println("buy something");
    }
}
public class ProxySubject implements Subject {  //创建代理类,实现抽象接口
    private RealSubject subject = null;

    @Override
    public void buy() {
        if (subject == null) {
            System.out.println("init real subject");
            subject = new RealSubject();
        }
        subject.buy();      //购买的时候,其实还是真实对象来购买的,毕竟最后要付钱的还是买家
    }

    public static void main(String[] args) {
        ProxySubject subject = new ProxySubject();
        subject.buy();//init real subject /n buy something
        System.out.println("*****");
        subject.buy();//buy something
    }
}

从上面代码和运行结果可以看到代理类里面的购买方法做了一次为 null 判断,主要是为了延时加载,当用到这个组件的时候再去实例化,这样节约了资源也分散了系统在启动时候初始化工作的压力。

除了静态代理,在 Java 中还有动态代理,其实现方式是通过 Java 内部的反射机制实现的。

下面只是实现动态代理的代码,目前只知道要这么写,但是还没深入去理解过。

public interface User {
    void login();
}

public class UserImp implements User {
    @Override
    public void login() {
        System.out.println("login");
    }
}

public class MyInvocation implements InvocationHandler {
    private Object object;

    public MyInvocation(Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("check one");
        method.invoke(object, args);//调用实际对象的方法
        System.out.println("check two");
        return null;
    }
}

public class ProxyTest {
    public static void main(String[] args) {
        UserImp user = new UserImp();
        MyInvocation m = new MyInvocation(user);
        User u = (User) Proxy.newProxyInstance(user.getClass().getClassLoader(), user.getClass().getInterfaces(), m);
        u.login();//创建代理对象
    }
}

Jdk 动态代理啊,待我这个星期把 JVM 刷一遍再回头来干翻你。

Comments
Write a Comment