概述
在生活中,我们可能会遇到这样的场景:我们想购买一些进口的商品,但是自己没有护照或通行证,这时候我们想到的就是代购,而代购的这个人也就是代理人,ta不是实际销售商品的人,只是起到代购的作用,在这中途ta可以赚点差价作路费(中途操作)。下边介绍的就是与这个场景很相似的设计模式——代理模式
代理模式
代理模式分为两种,一种是静态代理,另一种是动态代理。
静态代理:
代码实现:
//代理接口
public interface Buy {
void buy(int price);
}
//代购者
public class BuyProxy implements Buy {
private Buy buy;//真正要买的用户
public BuyProxy(Buy buy){
this.buy=buy;
}
@Override
public void buy(int price) {
System.out.println("use money:"+price);
buy.buy(price);
}
}
//真正需要购买的人
public class BuyUser implements Buy {
@Override
public void buy(int price) {
System.out.println("user use money:"+price);
}
}
//客户端
Buy user=new BuyUser();
Buy sProxy=new BuyProxy(user);//静态代理
sProxy.buy(300);
以上就是静态代理的一种实现,静态代理有以下的 特点:
- 代理类的字节码文件在程序运行之前就已经生成了
- 代理类和委托类的关系在运行之前就已经确定好了
优点:业务类(需要购买者)只需要关注自己本生的业务,提高了重用性,将实际的业务隐藏起来,只提供代理的方法
缺点:如果最上层的接口方法增加,那么真正业务类和代理类都有同时增加
动态代理
- 动态代理类需要实现InvocationHandler接口,并重写invoke方法,实现具体方法的逻辑
- Proxy:生成代理类的主类,它的创建方式有:
Proxy.newProxyInstance(代理类的CLassLoader,代理类接口,InvocationHandler对象)
Proxy.getProxyClass(loader, interfaces..,InvocationHandler对象)
//静态代理类
public class DynamicBuy implements InvocationHandler {
private Buy buy;
public DynamicBuy(Buy buy){
this.buy=buy;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if(method.getName().equals("buy")){
int price=(Integer) args[0];//第一个参数为price,这个我们可以预先知道
//代理对price的处理(抽路费等操作)
return method.invoke(buy, args);
}
return null;
}
}
//真正的业务类
public class BuyUser implements Buy {
@Override
public void buy(int price) {
System.out.println("user use money:"+price);
}
}
//客户端
Buy dProxy=(Buy) Proxy.newProxyInstance(user.getClass().getClassLoader(),
user.getClass().getInterfaces(),new DynamicBuy(user));//动态代理
dProxy.buy(100);
在生成的ProxyClass文件中可以看到生成的类:
public final class ProxyClass extends Proxy implements Buy{}
注意:使用动态代理要使用接口,不能使用类。
动态代理的 特点:在运行的时候采取找代理类,也就是在运行时才去确定要调用哪个方法。
优点:运行才去确定,提高扩展性和灵活性。
缺点:只能代理实现了接口的类。
代理模式的使用场景
- 在原来方法执行之前或者之后添加其他的操作
- 封装真实的业务逻辑,不暴露正在的主题
最后,祝大家节日安康。