単一責任の原則
バッドプラクティスから学ぶ 単一責任の原則 による柔軟なシステム設計
単一責任の原則 とは?
「単一責任の原則」(Single Responsibility Principle: SRP) とは、SOLID原則の一つであり、「1つのクラスは1つの責任のみを持つべきである」という原則です。
ここでいう「責任」とは、「変更する理由が1つだけある」という意味です。つまり、あるクラスに対する変更が複数の理由から発生する場合、そのクラスは複数の責任を持っていることになります。SRPに従えば、1つのクラスは1つの変更理由だけを持つようになります。
なぜ 単一責任の原則 が重要なのか?
単一責任の原則を守らない場合、以下のような問題が生じます。
- 複数の機能が絡み合っているため、変更時に予期しない副作用が発生しやすくなる。
- コードが複雑化し、可読性・保守性が低下する。
- 再利用が難しく、重複コードが増える。
一方、単一責任の原則を守れば、以下のようなメリットがあります。
- コードがシンプルになり、変更や修正が容易になる。
- クラスが明確な役割を持つため、理解しやすくなる。
- テストが容易になり、品質が向上する。
解説
では具体的な例を通じて、この原則を学びましょう。
店舗の売上レポートを作成して画面に表示し、さらにファイルに保存するクラスを考えます。
修正前のコード
問題点
- 上記のクラスは3つの責任を持っています:
- レポートの生成
- コンソールへの表示
- ファイルへの保存
- 例えば、レポートのフォーマットを変更するだけでこのクラスを修正する必要があり、それが表示や保存にも影響を与える可能性があります。
修正後のコード
解決された問題
- 各クラスが明確に1つの責任を持つようになり、変更時の影響範囲が明確になりました。
- 表示方法や保存方法が変更されても、レポートの生成部分に影響が及ばなくなりました。
- 各クラスを個別にテスト可能なため、品質も向上します。
まとめ
単一責任の原則を守ることで、各クラスがシンプルでわかりやすくなり、変更や修正が容易になります。保守性や拡張性が向上し、結果的にコードの品質が向上します。
練習問題 (1)
次のコードは、ユーザー認証とユーザー情報のメール送信を行うクラスです。
修正前のコード
修正後のコード
解説
元のコードでは、ユーザーの認証とメール送信の2つの異なる責任が同じクラスに含まれていました。そのため、例えばメールの内容や送信方法を変更する場合にも、認証機能を持つクラスを修正する必要があり、不要な影響を与えてしまう可能性がありました。
修正後のコードでは、それぞれの責任を専用のクラスに分割しています。「UserAuthenticator」は認証処理だけを担当し、「UserInfoMailer」はメール送信だけを担当しています。これにより、認証の仕組みを変更してもメール送信機能には影響がなくなり、その逆も同様です。
練習問題 (2)
次のコードは、注文の処理と請求書の作成を1つのクラスにまとめています。
修正前のコード
修正後のコード
解説
元のコードでは、注文の処理と請求書の生成という2つの別々の責任が1つのクラスにまとめられていました。そのため、注文処理のロジックを変更すると、請求書の生成部分に予期せぬ影響が及ぶ可能性がありました。
修正後は、「Order」クラスが注文処理のみに責任を持ち、「InvoiceGenerator」クラスが請求書作成のみに責任を持つように分割しました。これにより、注文処理と請求書生成が独立し、それぞれの変更が他方に影響を与えなくなりました。保守性・拡張性が向上し、今後の変更が容易になりました。