代码的坏味道(20)——过度耦合的消息链(Message Chains)

时间:2023-03-08 16:09:04

坏味道——过度耦合的消息链(Message Chains)

特征

消息链的形式类似于:obj.getA().getB().getC()

代码的坏味道(20)——过度耦合的消息链(Message Chains)

问题原因

如果你看到用户向一个对象请求另一个对象,然后再向后者请求另一个对象,然后再请求另一个对象……这就是消息链。实际代码中你看到的可能是一长串getThis()或一长串临时变量。采取这种方式,意味客户代码将与查找过程中的导航紧密耦合。一旦对象间关系发生任何变化,客户端就不得不做出相应的修改。

解决方法

  • 可以运用 隐藏委托关系(Hide Delegate) 删除一个消息链。

代码的坏味道(20)——过度耦合的消息链(Message Chains)

  • 有时更好的选择是:先观察消息链最终得到的对象是用来干什么的。看看能否以 提炼函数(Extract Method)把使用该对象的代码提炼到一个独立函数中,再运用 搬移函数(Move Method) 把这个函数推入消息链。

收益

  • 能减少链中类之间的依赖。
  • 能减少代码量。

代码的坏味道(20)——过度耦合的消息链(Message Chains)

何时忽略

  • 过于侵略性的委托可能会使程序员难以理解功能是如何触发的。

重构方法说明

隐藏委托关系(Hide Delegate)

问题

客户通过一个委托类来调用另一个对象。

代码的坏味道(20)——过度耦合的消息链(Message Chains)

解决

在服务类上建立客户所需的所有函数,用以隐藏委托关系。

代码的坏味道(20)——过度耦合的消息链(Message Chains)

提炼函数(Extract Method)

问题

你有一段代码可以组织在一起。

void printOwing() {
  printBanner();

  //print details
  System.out.println("name: " + name);
  System.out.println("amount: " + getOutstanding());
}

解决

移动这段代码到一个新的函数中,使用函数的调用来替代老代码。

void printOwing() {
  printBanner();
  printDetails(getOutstanding());
}

void printDetails(double outstanding) {
  System.out.println("name: " + name);
  System.out.println("amount: " + outstanding);
}

搬移函数(Move Method)

问题

你的程序中,有个函数与其所驻类之外的另一个类进行更多交流:调用后者,或被后者调用。

代码的坏味道(20)——过度耦合的消息链(Message Chains)

解决

在该函数最常引用的类中建立一个有着类似行为的新函数。将旧函数变成一个单纯的委托函数,或是旧函数完全移除。

代码的坏味道(20)——过度耦合的消息链(Message Chains)

引申阅读

欢迎继续阅读 代码的症与药 系列文章。