首页/开发/代码质量与评审速查/手法:Hide Delegate(隐藏委托关系)
重构手法62 条

手法:Hide Delegate(隐藏委托关系)

让服务方替你转发对下游对象的调用:调用方不再了解对象图内部,委托链变化被隔离在服务方;与 Remove Middle Man 是一对相反方向的权衡。

Hide Delegate 是什么

让服务方替调用方转发对下游对象的调用:调用方不再需要了解对象图的内部结构,委托链的变化被隔离在服务方内部。它是对「过长的消息链」的标准解法,但方向不能走过头——转发方法积累太多,就会滑向中间人坏味道,届时要反过来考虑 Remove Middle Man。

基本信息

场景客户端频繁 a.getB().getC()
做法在 A 上加转发方法,调用方改用新方法
权衡转发方法过多 → 反过来考虑 Remove Middle Man
配套为多实现准备接口时,转发本身就是价值

判断与落地

  • 调用方连续穿透两层以上、且只关心最终结果时,加转发方法
  • 同一个链条在多个调用点出现时,优先封装
  • 转发方法名应体现业务意图(leaderName),而不是复刻结构(departmentLeader)
  • 转发方法里顺带归一错误语义:下游异常转成服务方自己的错误类型
  • 链条中间对象是公开 DTO 时不必隐藏,强行封装只会绕路
  • 转发方法增加到超过半数时停下来重新评估,可能该用 Remove Middle Man

Java 示例

Java 示例
// 之前
String leader = manager.department().leaderName();
int count     = manager.department().memberCount();

// 之后:Department 的细节被隐藏,名字体现意图
class Manager {
    private final Department department;

    String leaderName() { return department.leaderName(); }
    int memberCount()   { return department.memberCount(); }
}

String leader = manager.leaderName();
int count     = manager.memberCount();

与 Remove Middle Man 的拉锯

信号倾向说明
调用方频繁穿透内部对象图Hide Delegate隐藏变化来源
类里过半方法是纯转发Remove Middle Man转发不再提供价值
转发含校验或组合继续保留职责确实在服务方
接口为多实现准备继续保留隔离实现替换
机械隐藏所有链条会让中间人膨胀:转发方法越多,类越厚,改动时还要跟着穿透。真正该封装的是「调用方不该知道的内部结构」,而不是所有能被转发的方法。
转发时要注意异常语义:下游的异常类型直接透出,会让调用方依赖下游实现;换成服务方自己的错误类型,才能在没有痛感的情况下替换下游。

易错点

  • 机械隐藏所有链条:中间人膨胀,类变厚且改动要层层穿透
  • 转发忘记处理异常语义:下游错误被吞掉或换型,调用方 catch 失配
  • 转发方法名复刻结构而非意图:封装完成但可读性没有提升
  • 调用方绕过封装继续穿透:新旧两种写法并存,封装形同虚设

数据来源与参考

  • 《重构》第 2 版 · 第 7 章(Hide Delegate)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌