JAVA与模式2:代理模式proxy

2017-10-15  本文已影响0人  洋_6653

1.静态代理

什么是代理模式?

代理模式的定义:代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。举例说明,就是一个人或者一个机构代表另一个人或者另一个机构采取行动。在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之前起到中介的作用。

应用场景举例:通过上面的代理模式描述我们可以知道,其目的就是为了控制对象引用,生活场景中我们以买车为例,如果我们要买一辆轿车必须通过汽车4S店,汽车4s店就是充当代理角色,其目的就是控制买车客户的买车行为,必须通过汽车4S店才能从汽车厂商买一辆车。

public interface IBuyCar {

void buyCar(int price);

}

---------------

public class Customer implements IBuyCar {

private int cash;

@Override

public void buyCar(int price) {

System.out.println("buyCar"+" 花了这么多钱:"+price+" $");

this.cash = cash -price;

}

public int getCash() {

return cash;

}

public void setCash(int cash) {

this.cash = cash;

}

}

==============================================

public class Proxy4s implements IBuyCar {

private Customer customer;

public Proxy4s(Customer cs){

this.customer = cs;

}

@Override

public void buyCar(int price) {

if(customer.getCash()>=price)

this.customer.buyCar(price);

else

System.out.println("不够钱买车~ 撤销");

}

public static void main(String[] args) {

Customer cs = new Customer();

cs.setCash(120000);

Proxy4s s4 = new Proxy4s(cs);

s4.buyCar(128000);

System.out.println("customer 还剩余:"+cs.getCash());

 }

}

通过代理模式实现权限控制 通过上面的例子,我们可能有个疑问,难道就不能直接去厂家买车吗?当然可以,如果在使用场景中实现类能满足要求时,我们当然可以直接实现类,但当实现类不能满足要求,要扩展需求,根据开闭原则你又不能修改实现类代码,这时你就用代理类。比如购买一辆车我们要对客户进行一个购车款审核,如果符合条件就买车,不符合要求我们就告知客户购车款不足。

2.动态代理模式:

public class DynamicProxy implements InvocationHandler {

Object object;

public DynamicProxy(Object obj) {

this.object = obj;

}

/** 覆盖InvocationHandler接口中的invoke()方法

* 更重要的是,动态代理模式可以使得我们在不改变原来已有的代码结构

* 的情况下,对原来的“真实方法”进行扩展、增强其功能,并且可以达到

* 控制被代理对象的行为,下面的before、after就是我们可以进行特殊

* 代码切入的扩展点了。

*/

@Override

public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {

Object result = method.invoke(this.object, args);

return result;

}

public static void main(String[] args) {

Customer cs = new Customer();

InvocationHandler handler = new DynamicProxy(cs);

/** 通过Proxy的newProxyInstance方法来创建我们的代理对象,我们来看看其三个参数

* 第一个参数 handler.getClass().getClassLoader() ,我们这里使用handler这个类的ClassLoader对象来加载我们的代理对象

* 第二个参数customer.getClass().getInterfaces(),我们这里为代理对象提供的接口是真实对象所实行的接口,表示我要代理的是该真实对象,这样我就能调用这组接口中的方法了

* 第三个参数handler, 我们这里将这个代理对象关联到了上方的 InvocationHandler 这个对象上

**/

IBuyCar buyCar = (IBuyCar) Proxy.newProxyInstance(handler.getClass().getClassLoader(),

cs.getClass().getInterfaces(),

handler);

buyCar.buyCar(118000);

}

}

上一篇下一篇

猜你喜欢

热点阅读