0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Ateam LifeDesignAdvent Calendar 2024

Day 25

早期リターンが必要な場合、そうでない場合

Last updated at Posted at 2024-12-25

早期リターンとは

早期リターンを行うことで、特定の条件を満たした場合にすぐに関数から抜け出すことができます。
必要な条件が満たされなかった場合に関数の処理を無駄に実行しないことで、保守性にも繋がります。
またコードの読みやすさにも繋がります。

NG例

ユーザー情報の種類(infoType)に基づいてその情報を取得する目的の関数です。

export const getUserInfo = (
  infoType: string,  
  user: {
    details: {
      [key: string]: number | null;
    };
  },
  userInfoItems: {
    [key: string]: {
      [key: string]: string;
    };
  }
) => {
  const detailValue = user.details[infoType];

  if (infoType === 'age') { 
    return userInfoItems.age === null ? "" : userInfoItems.age[detailValue]
  }

  if (infoType === 'hobby') { 
    return userInfoItems.hobby === null ? "" : userInfoItems.hobby[detailValue]
  } 

   if (detailValue === null) {
    return "" ? userInfoItems[infoType][detailValue];
  }
};

上記のコードは関数の途中で終了(リターン)するポイントがなく、条件の最後でのみ結果がresultに集積されます。

また、NG例では条件の判定をする順番が適切ではありません。まずはdetailValue === nullが通ってからでなければ、infoType === 'age'infoType === 'hobby'が正しく動かないはずなので、detailValue === nullの条件は一番初めにリターンする方が適切です。

OK例

export const getUserInfoEarlyReturn = (
  infoType: string,  
  user: {
    details: {
      [key: string]: number | null;
    };
  },
  userInfoItems: {
    [key: string]: {
      [key: string]: string;
    };
  }
) => {
  const detailValue = user.details[infoType];

  if (detailValue === null) return "";


  if (infoType === 'age') {
    return userInfoItems.age[detailValue];
  }

  if (infoType === 'hobby') {
    return userInfoItems.hobby[detailValue];
  }

  return userInfoItems[infoType]?.[detailValue];
};

OK例ではnull条件を最初にチェックすることで、結果に応じた即時リターンを可能にして効率を高めています。

ロジックフローが明確になることで、保守性が向上します。

このように、早期リターンは本質的にコードをシンプルにし、特定の条件が満たされなくなった時点で処理を中断させられる点で非常に便利です。
しかし、すべてのケースにおいて早期リターンが適用されるわけではありません。

早期リターンが適切でない場合

その1つが「多段階処理が必要な場合」です。

具体例

export const processAllSteps = (data) => {
  if (!initialize(data)) {
    console.error('Initialization failed');
    return;
  }
  
  if (!loadData(data)) {
    console.error('Data loading failed');
    return;
  }
  
  if (!transformData(data)) {
    console.error('Data transformation failed');
    return;
  }
  
  finalizeProcessing(data);
};

上記の例では初期化、データ読み込み、データ変換のすべてが成功した場合にのみ実行されます。失敗した場合、そこでプロセスは終了します。

各処理ステップ(initialize, loadData, transformData)が独立しており、どれか一つが失敗するとその時点で処理を止め、以降のステップを中断します。
これにより、終わるべき処理やクリーンアップが実行されないままリターンしてしまいます。

早期リターンが導入されると、何が完了し、何が完了していないかを把握するのが難しくなることがあります。

早期リターンを用いるならば、各リターンポイントで保証するべき後処理を明確にし、処理が途中で止まっても害が少ないロジック構造を持たせる必要があります。

まとめ

早期リターンは便利ですが、使用箇所や主題によっては、返ってコードが不明瞭になることを避けるため、慎重に採用する必要があります。

適切な設計指針に従って、利点と欠点のバランスを計ることが重要です。

参考

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?