Skip to content

允许重复代码

耦合性

作为开发者,我们经常会把跨多个页面或组件的重复代码整合于一个 Hook 或组件中来实现代码的共用。 通过将重复代码整合到一个组件或 Hook 中,使得代码具有高内聚性(好代码的特征之一),从而能够同时修改那些需要一起修改的代码。

然而,这也可能引发不必要地耦合性,导致在修改公共组件或 Hook 时,受影响的代码范围扩大,修改代码反而变得更加困难。

起初因功能相似而合并的公共代码,后来可能会根据各页面的特殊需求而逐渐变得复杂起来。 而且,每次修改公共代码时,都必须逐一测试对其依赖的代码,这反而会让代码修改更加困难。

📝 代码示例

下面有一个 Hook,它接受维修信息作为参数,如果系统当前处于维修中状态,就会打开底部动作条(bottom sheet)。如果用户同意接收通知,则会进行日志记录,并随后关闭当前屏幕。

typescript
export const useOpenMaintenanceBottomSheet = () => {
  const maintenanceBottomSheet = useMaintenanceBottomSheet();
  const logger = useLogger();

  return async (maintainingInfo: TelecomMaintenanceInfo) => {
    logger.log("打开维修底部动作条");
    const result = await maintenanceBottomSheet.open(maintainingInfo);
    if (result) {
      logger.log("点击维修底部动作条上的同意接收通知");
    }
    closeView();
  };
};

这段代码因在多个页面中反复使用,被提取为一个公共 Hook。

👃 闻代码

耦合性

这个 Hook 之所以被通用化,是因为其包含了很多页面共同反复用到的逻辑。不过,在享受其带来的便利时,需要留意未来可能出现的各种代码变更的情况。

  • 每个页面需要日志记录的值不同时?
  • 某些页面即使在关闭维修底部动作条时也不需要关闭整个屏幕时?
  • 需要在底部动作条中显示不同文本或图像时?

上述 Hook 为了灵活对应代码变更需求,可能需要接受一些复杂的参数。 而且,每次修改这个 Hook 时,都需要测试所有使用该 Hook 的页面,以确保动作的正常运行。

✏️ 尝试改善

即便重复的代码看上去有些冗余,有时候接受这种重复代码也不失为一种好方法。

需要积极与同事沟通,准确理解维修底部动作条的动作原理。 如果页面上日志记录的值相同,维修底部动作条的动作一致,且其外表相同,并且预计将来也会保持现状,那么我们可以通过通用化提高代码的内聚性。

但是,如果每个页面的行为都可能有所不同,那么不追求通用化,而是允许代码重复,可能是更好的选择。