代理模式 vs 装饰器模式
代理模式 vs 装饰器模式
基于当前项目中 Client.java / Proxy.java / Host.java / Rent.java 代码的分析。
当前代码结构
// 抽象接口
public interface Rent {
void rent();
}
// 真实角色:房东
public class Host implements Rent {
public void rent() {
System.out.println("房屋出租");
}
}
// 代理角色:中介
public class Proxy implements Rent {
private Host host;
public Proxy(Host host) {
this.host = host;
}
public void rent() {
seeHouse(); // 中介职责:带人看房
host.rent(); // 房东职责:出租房子
fare(); // 中介职责:收中介费
}
public void seeHouse() {
System.out.println("带房客看房");
}
public void fare() {
System.out.println("收中介费");
}
}
// 客户端
public class Client {
public static void main(String[] args) {
Host host = new Host();
Proxy proxy = new Proxy(host);
proxy.rent(); // 客户找的是中介,不是房东
}
}
结论:这是代理模式(Proxy Pattern)
当前代码是标准的静态代理模式,不是装饰器模式。
核心区别
| 维度 | 代理模式 | 装饰器模式 |
|---|---|---|
| 目的 | 控制对对象的访问 | 动态增强/扩展对象功能 |
| 被代理/被装饰对象来源 | 通常在内部创建或持有具体类型的引用 | 通常通过构造函数注入抽象接口,可以层层嵌套 |
| 关注点 | 访问控制、延迟加载、权限校验 | 功能叠加、组合增强 |
关于"增强"的疑问
seeHouse()+host.rent()+fare()不也是在原有功能上增强吗?
表面上确实都在原功能前后加了东西,但代理模式和装饰器模式的本质区别不在于"有没有增强",而在于"意图"和"与被增强对象的关系"。
代理模式的附加操作
附加操作是代理角色自身的职责,与目标对象的业务无关:
seeHouse() → 这是"中介"这个角色的职责(带人看房),不是房东的职责
host.rent() → 这是房东的职责(出租房子)
fare() → 这也是"中介"的职责(收中介费),不是房东的职责
seeHouse() 和 fare() 是中介自身的业务逻辑,和"租房"这件事没有直接的功能增强关系。它们是代理角色天然要干的事,不是为了增强 rent() 而加的。
语义:"我来帮你处理这件事"
装饰器模式的增强
增强是在扩展目标功能本身,服务于同一业务语义:
// 如果是装饰器模式,代码应该是这样:
public class RentDecorator implements Rent {
private Rent rent; // 持有抽象接口,而非具体类
public RentDecorator(Rent rent) {
this.rent = rent;
}
public void rent() {
System.out.println("精装修"); // 让房子更好 → 增强 rent 本身
rent.rent();
System.out.println("赠送家具"); // 让租房更划算 → 增强 rent 本身
}
}
这里的"精装修"和"赠送家具"是在增强"租房"这件事的价值,它们和 rent() 是同一业务语义的延伸。
语义:"我把这件事做得更好/更丰富"
代理模式的两个关键特征(在当前代码中的体现)
Proxy持有的是Host具体类型,而不是Rent接口 → 代理模式的典型特征- 场景语义:Client 找的是"中介"(代理),而不是"房东",客户无法直接访问房东 → 代理模式控制了对真实对象的访问
一句话总结
| 模式 | 附加操作的性质 | 语义 |
|---|---|---|
| 代理 | 代理角色自己的职责(控制、中介服务) | "我来帮你处理这件事" |
| 装饰器 | 对目标功能本身的扩展 | "我把这件事做得更好/更丰富" |
当前代码中,Proxy 是"帮房东处理租房流程",不是"让租房这件事变得更好",所以是代理模式。
浙公网安备 33010602011771号