零弐壱蜂

[ソフトウェア開発] 関数は1つのことを行うべき(単一責任)

7 min read

概要

ソフトウェア開発において、関数を設計する際の重要な基本原則として「関数は1つのことだけを行うべき」という考え方がある。

この考え方は、ソフトウェア設計における重要な原則である「単一責任の原則(Single Responsibility Principle, SRP)」に基づいている。単一責任の原則とは、モジュールや関数が1つの責務に集中するべきであるという考え方であり、これによりコードの可読性や保守性が向上し、さらに再利用性も高まる。

Note

本記事では、JavaScriptやTypeScriptなどのプログラミング言語を例に説明しているが、単一責任の原則はプログラミング言語に依存せず、ソフトウェア設計全般に適用される原則である。

原則の目的

単一責任の原則を遵守することにより、以下のようなメリットが得られる。

  1. 目的の明確化
    関数は単一のタスクまたはコンセプトを扱うべきであり、複数のアクションや責務を持たせるべきではない
    これにより、その関数が何を行うかの意図が明確になり、可読性が向上する
  2. シンプルな構造の実現
    関数は短く、直感的に理解できるようにする。複雑な処理が必要な場合は、それを複数の小さな関数に分割する
    これによりコードの管理が容易になり、必要な部分だけを再利用できる
  3. 単純な構造を維持
    if などを使って複数の作業や条件分岐を1つの関数内に入れることは、その関数が複数の責務を持っている可能性が高い
    これを避けることで、関数のテストが簡単になり修正が安全に行える

適用方法

単一責任の原則を実践するためには、以下のような方法がある。

  1. 機能を1つに絞る
    関数を作成する際、まずその関数が「何をするか」を明確にする
    そして、それの目的以外の処理は含めず別の関数に分離する
  2. 責務の分割
    複雑な処理は、それぞれが特定の役割を持つ複数の小さな関数に分ける
  3. 条件の乱立を避ける
    関数内で複数の条件分岐や責務が混在していないか確認する

具体例

以下に、単一責任の原則を適用したコード例を示す。

改善が必要な例

// 複数の責務を持つ関数
function processAnimal(animal: string) {
  if (animal === 'cat') {
    console.log('にゃあ!');
    console.log('猫にご飯を与えます。');
  } else if (animal === 'dog') {
    console.log('わん!');
    console.log('犬を散歩に連れて行きます。');
  } else {
    console.error('知らない動物です。');
  }
}

問題点

  • 「動物の鳴き声」と「動物ごとの行動」という異なる処理が1つの関数に混在している
  • 責務が分散しており、テストやリファクタリングの際、影響範囲が広くなってしまう

改善後の例

// 責務を分離した関数
function makeSound(animal: string) {
  if (animal === 'cat') {
    console.log('にゃあ!');
  } else if (animal === 'dog') {
    console.log('わん!');
  } else {
    console.error('知らない動物です。');
  }
}

function feedCat() {
  console.log('猫にご飯を与えます。');
}

function walkDog() {
  console.log('犬を散歩に連れて行きます。');
}

改善点

  • 「動物の音声出力(makeSound)」と「行動処理(feedCatwalkDog)」を別々の関数に分離
  • 各関数がそれぞれ1つの責務に集中しているため、再利用性が高くなる

メリットとデメリット

単一責任の原則を適用することにより、以下のようなメリットとデメリットがある。

メリット

  • コードの整理が容易:
    各関数の役割が明確になり、コードの構造が理解しやすくなる
  • 再利用性の向上:
    機能が明確に分かれているため、必要な部分だけをほかの箇所で簡単に利用できるようになる
  • 変更や修正が簡単:
    責務が限定されているため、安全かつ迅速に修正が可能

デメリット

  • 関数の増加:
    小さな関数が増えることで、全体の把握が難しくなる可能性がある
  • 性能への影響:
    関数呼び出し回数が増えることで、極端な場合にパフォーマンスが低下する可能性がある

まとめ

「関数は1つのことだけを行う」という原則を守ることは、モジュール性、保守性、再利用性の高いコードを実現するための基本である。

これを遵守することで、コードの理解が容易になり、バグの発生を抑えることができる。また、将来的な機能追加や変更もより安全に行えるようになる。