代理模式
概述
委托者: 实际服务提供者
代理者: 中间商
客户: 服务的消费者
优缺点
优点:
- 隐匿委托者
- 客户和委托者实现解耦, 在不修改委托者的情况下可做额外操作.
分类
根据代理类在运行前是否存在,分为:
静态代理: 运行前已存在代理类
动态代理: 运行前未存在代理类
场景举例
厂家(Vendor)生产产品, 厂家可以直接销售给用户(Customer), 也可以通过代理商(Agent)销售给用户.代理商不直接囤货,有客户需求再让
厂家发货销售. 类似于微商.
Vendor -> Customer
有的地方只有一级代理, 直接面向用户:
Vendor -> Agent -> Customer
有的地方有一级代理商和二级代理商, 其中二级代理商直接面向用户, 一级代理商做厂家和二级代理商的中间媒介,根据实际需求做一些事情.
比如给二级代理商售前培训, 售后的结算等等.
Vendor -> Proxy -> Agent -> Customer
业务实现
销售接口:
public interface Sell {
/**
* 售卖
*/
void sell();
}
生产者:
public class Vendor implements Sell {
@Override
public void sell() {
System.out.println("Vendor sell.");
}
}
直接销售代理:
public class BusinessAgent implements Sell {
private Vendor vendor;
public BusinessAgent(Vendor vendor) {
this.vendor =vendor;
}
@Override
public void sell() {
System.out.println("BusinessAgent sell.");
// 代理商只卖给学生, 即为在不修改委托的情况下增加额外操作.
if (isStudent()) {
vendor.sell();
}
}
private boolean isStudent() {
boolean isStudent = new Random().nextBoolean();
System.out.println("isStudent:" + isStudent);
return isStudent;
}
}
动态代理拦截:
public class DynamicProxy implements InvocationHandler {
//接口的实现类
private Object object;
public DynamicProxy(Object o) {
this.object = o;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("=========给代理商培训==========");
//实现类对象object调用方法method并传入参数args
Object o = method.invoke(object, args);
System.out.println("=========售后维护结算==========");
return o;
}
}
生成动态代理文件:
System.out.println("==========exe:dynamicProxy==========");
//生成一个二级代理商
BusinessAgent agent = new BusinessAgent(new Vendor());
//根据实际需要生成一个一级代理
DynamicProxy dynamicProxy = new DynamicProxy(agent);
//生成动态代理文件
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
//获取Sell接口的实例
Sell sell = (Sell) Proxy.newProxyInstance(Sell.class.getClassLoader(), new Class[]{Sell.class}, dynamicProxy);
//售卖产品
sell.sell();
动态代理类文件:
public final class $Proxy0 extends Proxy implements Sell {
private static Method m1;
private static Method m2;
//Sell的的sell方法
private static Method m3;
private static Method m0;
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m2 = Class.forName("java.lang.Object").getMethod("toString");
//获取Sell 的 sell方法
m3 = Class.forName("net.devwiki.pattern.proxy.Sell").getMethod("sell");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
public $Proxy0(InvocationHandler var1) throws {
super(var1);
}
public final boolean equals(Object var1) throws {
try {
return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final String toString() throws {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
//覆写Sell类的sell方法
public final void sell() throws {
try {
// h为InvocationHandler的实例, 调用DynamicProxy的invoke方法
//进而调用实现类的sell方法
//如果外部传入的是Vendor则直接是调用Vendor的sell
//如果外部传入的是BusinessAgent, 则中间添加学生过滤
super.h.invoke(this, m3, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final int hashCode() throws {
try {
return (Integer)super.h.invoke(this, m0, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
}