特点
代理模式表示代理一个类的功能,主要关注点在于控制。属于结构性模式。一般分为静态代理和动态代理,其中静态代理在结构上与适配器模式、包装器模式非常相似。动态代理一般会被分为JDK动态代理和Cglib动态代理,前者只能代理接口,后者可代理具体类。
实现示例
静态代理需要代理对象与被代理对象都实现同一个接口,然后在代理对象内实现控制逻辑。
模拟商品代理的过程,当商品生产后,工厂售卖商品,代理商代理工厂也售卖商品,代理商售卖商品前需要对商品加价处理。
商品类
public class Goods {
private BigDecimal price = new BigDecimal("1200.00");
private String name = "手机";
public void addPrice(String val){
this.price = this.price.add(new BigDecimal(val));
}
}
售卖接口
public interface Sales {
void sale(Goods goods);
}
工厂类
@Slf4j
public class Factory implements Sales {
@Override
public void sale(Goods goods) {
log.info("售卖商品: {}",goods);
}
}
代理商类
@Slf4j
public class RestProxy implements Sales {
private Sales sales;
public RestProxy(Sales sales) {
this.sales = sales;
}
@Override
public void sale(Goods goods) {
beforeShow(goods);
this.sales.sale(goods);
}
private void beforeShow(Goods goods) {
goods.addPrice("500.00");
log.info("售卖商品前加价500: {}",goods);
}
}
测试代码
@Test
public void testRestProxy(){
Goods goods = new Goods();
Sales factory = new Factory();
factory.sale(goods);
Sales restProxy = new RestProxy(factory);
restProxy.sale(goods);
}
日志信息
2021-03-26 10:53:39.372 INFO 9500 --- [ main] org.example.proxy.rest.Factory : 展示商品: Goods(super=org.example.proxy.core.Goods@d215c1e, price=1200.00, name=手机)
2021-03-26 10:53:39.375 INFO 9500 --- [ main] org.example.proxy.rest.RestProxy : 展示商品前加价500: Goods(super=org.example.proxy.core.Goods@1294c6ae, price=1700.00, name=手机)
2021-03-26 10:53:39.375 INFO 9500 --- [ main] org.example.proxy.rest.Factory : 展示商品: Goods(super=org.example.proxy.core.Goods@1294c6ae, price=1700.00, name=手机)
与适配器、包装器模式区别
代理模式主要关注点是对接口的一种控制,多数主要是在接口方法执行之前和之后的一些处理,不以增加接口数量为目的,并且代理对象和被代理对象是实现同一个接口,拥有相同的方法属性。
适配器主要关注点是将2个不同的接口进行适配,让接口有更强大的兼容性。
包装器模式关注点是对接口的增强,增强类与被增强类需要在同一继承体系类。