[ソフトウェア開発] 関数は1つのことを行うべき
6 min read
概要
関数設計では、「関数は1つのことを行うべき」という考え方が基本原則の1つとされている。
この考え方は、ソフトウェア設計における重要な原則である「単一責任の原則(Single Responsibility Principle, SRP)」に基づいている。単一責任の原則とは、モジュールや関数が1つの責務に集中するべきであるという考え方であり、これによりコードの可読性や保守性が向上し、さらに再利用性も高まる。
この原則を守ることで、理解しやすく変更にも強いコードを実現できるため、ソフトウェアエンジニアリングの中でも特に重要なルールとされている。
原則の目的
- 明確な目的を持つ
関数は単一のタスクまたはコンセプトを扱うべきであり、複数のアクションや責務を持たせるべきではない
これにより、関数の意図が明確になり、可読性が向上する - 簡潔さ
関数は短く、直感的に理解できるようにする。複雑な処理は、複数の小さな関数に分割することで管理しやすくなり、リファクタリングや再利用が容易になる - 条件や複数の責務を避ける
and
、or
、if
などで複数のタスクや条件を表現する関数は、責務が分散している可能性が高い
これを避けることで、関数のテストや修正が簡単になる
適用方法
- 単一のタスクに絞る
関数を作成する際、その関数が「何をするか」を明確にし、それ以外の処理を含めない - 責務の分割
複雑な処理を複数の小さな関数に分解し、それぞれが特定のタスクを担当するように設計する - 条件の乱立を避ける
関数内で複数の条件分岐や責務が混在していないか確認する
良い例と悪い例
悪い例
// 複数の責務を持つ関数
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
) と行動処理 (feedCat
、walkDog
) を別々の関数に分離 - 関数がそれぞれ1つの責務に集中しているため、再利用性が高くなる
利点と欠点
利点
- コードの整理:
関数が1つのタスクに限定されることで、コードがモジュール化され、理解しやすくなる - 再利用性の向上:
独立した関数は、ほかの箇所で簡単に利用できる - 変更や修正が簡単:
責務が限定されているため、安全かつ迅速に修正可能
欠点
- 関数の増加:
小さな関数が増えることで、コードの管理が煩雑になる可能性がある - 性能への影響:
関数呼び出しが増えることで、極端な場合にパフォーマンスが低下する可能性がある
まとめ
「関数は1つのことを行う」という原則を守ることは、モジュール性、保守性、再利用性の高いコードを実現するための基本である。これにより、コードの理解が容易になり、バグの発生する可能性が減るだけでなく、将来的な変更や拡張も安全に行える。