居民李姐最近发现小区的快递服务焕然一新。原来的露天货架换成了智能快递柜,快递员扫码存件、居民取件码开柜,还能代收生鲜冷藏包裹。更神奇的是,这个柜子能同时处理顺丰、京东、邮政等所有快递公司的包裹,自动发送取件提醒,甚至能识别异常包裹自动报警…
1. 抽象主题(Subject) :快递服务标准接口
2. 真实主题(Real Subject):顺丰、京东快递服务商
3. 代理(Proxy):智能快递柜的智能处理层
/**
* 抽象主题:快递服务标准接口
* 定义所有快递公司必须实现的存/取方法
*/
interface DeliveryService {
void storePackage(String trackingNumber); // 存件操作
String fetchPackage(String trackingNumber); // 取件操作
}
/**
* 真实主题:顺丰快递服务实现类
* 包含核心业务逻辑,但缺乏安全控制和扩展功能
*/
class SFExpress implements DeliveryService {
@Override
public void storePackage(String trackingNumber) {
System.out.println("[顺丰] 包裹入库: " + trackingNumber);
}
@Override
public String fetchPackage(String trackingNumber) {
return "[顺丰] 包裹内容:电子产品";
}
}
/**
* 代理:智能快递柜的智能处理层(顺丰代理)
*/
class SFProxy implements DeliveryService {
private SFExpress sfExpress;
public SFProxy(DeliveryService service) {
this.sfExpress = service;
}
public void store(String code) {
checkSecurity(code); // 安全校验
sfExpress.store(code);
sendNotification(code); // 发送通知
}
public String pickup(String code) {
verifyCode(code); // 验证取件码
return sfExpress.pickup(code);
}
}
问题场景
当需要支持多家快递公司时,传统静态代理面临挑战:
// 顺丰代理
class SFProxy extends LockerProxy { /* 重复实现 */ }
// 京东代理
class JDProxy extends LockerProxy { /* 重复代码 */ }
// 邮政代理
class PostalProxy extends LockerProxy { /* 重复代码 */ }
四大痛点
动态代理代码实现:
import java.lang.reflect.*;
/**
* 智能快递柜代理处理器(动态代理核心)
* 统一处理各家快递公司的增强需求
*/
class SmartLockerHandler implements InvocationHandler {
private Object target; // 被代理的快递公司实例
private Map<String, String> verificationCodes = new HashMap<>(); // 取件码缓存
// 绑定目标对象
public Object bind(Object target) {
this.target = target;
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
this);
}
// 统一处理方法调用
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String trackingNumber = (String) args[0];
// 存件增强逻辑
if (method.getName().equals("storePackage")) {
generateVerificationCode(trackingNumber); // 生成取件码
notifyUser(trackingNumber); // 发送通知
checkSecurity(trackingNumber); // 安全扫描
}
// 取件增强逻辑
if (method.getName().equals("fetchPackage")) {
if (!verifyCode(trackingNumber)) {
throw new SecurityException("取件码验证失败");
}
}
// 执行原始方法
Object result = method.invoke(target, args);
// 后置处理
if (method.getName().equals("storePackage")) {
logStorage(trackingNumber); // 记录存件日志
}
return result;
}
// 私有增强方法(以下为代理扩展功能)
private void generateVerificationCode(String trackingNumber) {
String code = "VC" + trackingNumber.hashCode();
verificationCodes.put(trackingNumber, code);
System.out.println("生成取件码: " + code);
}
private void notifyUser(String trackingNumber) {
System.out.println("短信通知: 取件码已发送至用户手机");
}
private void checkSecurity(String trackingNumber) {
System.out.println("安全扫描: X光检测包裹安全性");
}
private boolean verifyCode(String trackingNumber) {
return verificationCodes.containsKey(trackingNumber);
}
private void logStorage(String trackingNumber) {
System.out.println("存储日志: " + trackingNumber + " 存入时间 " + LocalDateTime.now());
}
}
客户端演示类:
/**
* 客户端演示类 - 展示动态代理四大优势:
* 1. 多服务统一处理 2. 功能热插拔 3. 零代码入侵 4. 集中式控制
*/
public class CommunityClient {
public static void main(String[] args) {
// 创建代理处理器(快递柜实例)
SmartLockerHandler smartLocker = new SmartLockerHandler();
// 动态代理不同快递公司(无需创建多个代理类)
DeliveryService sfProxy = (DeliveryService) smartLocker.bind(new SFExpress());
DeliveryService jdProxy = (DeliveryService) smartLocker.bind(new JDLogistics());
System.out.println("======= 顺丰快递流程 =======");
processDelivery(sfProxy, "SF20230715001");
System.out.println("\n======= 京东物流流程 =======");
processDelivery(jdProxy, "JD20230715002");
}
private static void processDelivery(DeliveryService service, String trackingNumber) {
// 存件操作(自动增强)
service.storePackage(trackingNumber);
// 取件操作(自动验证)
try {
String content = service.fetchPackage(trackingNumber);
System.out.println("取件成功: " + content);
} catch (SecurityException e) {
System.out.println("取件失败: " + e.getMessage());
}
}
}
/* 运行输出:
======= 顺丰快递流程 =======
生成取件码: VCSF20230715001
短信通知: 取件码已发送至用户手机
安全扫描: X光检测包裹安全性
[顺丰] 包裹入库: SF20230715001
存储日志: SF20230715001 存入时间 2023-07-15T09:30:00
取件成功: [顺丰] 包裹内容:电子产品
======= 京东物流流程 =======
生成取件码: VCJD20230715002
短信通知: 取件码已发送至用户手机
安全扫描: X光检测包裹安全性
[京东] 包裹入库: JD20230715002
存储日志: JD20230715002 存入时间 2023-07-15T09:30:05
取件成功: [京东] 包裹内容:生鲜食品
*/
革命性优势
静态代理 | 动态代理 | |
---|---|---|
扩展能力 | 每公司需新代理类 | 一套处理器适配所有快递公司 |
维护成本 | 修改N个代理类 | 修改1个处理器即可 |
执行效率 | 直接调用(快) | 反射调用(毫秒级损耗) |
功能迭代 | 需修改每个代理类 | 统一增强所有服务 |
技术复杂度 | 简单但冗余 | 复杂但优雅 |
行业级应用场景
框架集成实例
// Spring AOP事务管理(动态代理实现)
@Transactional
public void placeOrder() {
// 自动添加事务边界
}
// MyBatis Mapper代理(接口方法转SQL)
public interface ProductMapper {
@Select("SELECT * FROM products WHERE sku = #{sku}")
Product selectBySku(String sku); // 动态生成实现类
}
从静态代理到动态代理的演进,体现了软件设计的核心原则:
行业应用:Spring框架的声明式事务管理,通过动态代理在运行时为DAO层方法自动添加事务边界,无需侵入业务代码
通过动态代理技术,开发者能构建出弹性更强、更易维护的系统架构,这是现代框架设计的基石之一。