プログラミングマガジン

プログラミングを中心にIT技術をできるだけわかりやすくまとめます。

  • ホーム
  • オブジェクト指向
  • 【オブジェクト指向】「単一責任の原則」
 
 
     
  • サーバー言語  
    • Python
    • Ruby
    • PHP
    • SQL
  •  
  • インフラ  
       
    • AWS
    •  
    • 基本
    • Git
  • Web
       
    • Web開発
    • JavaScript
    • Vue.js
    • React
  •  
  • 設計  
       
    • 実装設計
    • DB設計
  • 問い合わせ
  

【オブジェクト指向】「単一責任の原則」

03.26

  • miyabisan2
  • 1件のコメント

この記事は2分で読めます

概念的な話

クラスが担う責任はたった一つにするべきという原則。クラスを仕様変更する理由を一つにする。(複数の仕様で一つのクラスを使い回さない)

「単一責任の原則」は二つの側面がある。

単一責任の原則は人によって言っていることが微妙に変わる印象を受けました。

  • クラスの汎用性を上げるために意味がわかる最小単位までクラスを分けること
  • 「仕様の変更」において一つの理由がある単位までクラスを分けること

前者は「細かい粒度」、後者は「大きな粒度」でクラスを分ける場合の考え方のような気がします。

クラスの汎用性を上げるために意味がわかる最小単位までクラスを分けること

なので、実際に意識することとしては基本クラスって「値」と「メソッド」を持つものだと思うのですが基本的にはこれ以上分けられないくらいまでクラスを最小化すること(これ以上分けてしまうとこのクラスの意味が通じなくなってしまうなと思える単位まで最小化する)だけを意識すれば良いです。変更理由がどうとか考え始めると話が非常にややこしくなってしまうと思いますので。(基本的には、インスタンス変数を使ってないメソッドが発生してきたらそのメソッドは怪しいという目で見ていただく形だと思います。)

例

ユーザークラスがあった場合に以下のようなインスタンス変数を思い浮かべます。

  • ユーザーID
  • ユーザー名
  • 住所

ユーザーIDや、ユーザー名、住所なども分けるかという点ですが、結論から言えばこれから実装するシステムによります。例えば、ユーザーIDなどが独自のルールを持っていたりだとかする場合はユーザーIDクラスなどのように分けた方が良いでしょう。

仕様変更において一つの理由がある単位までクラスを分けること

例1

家具の販売システムを構築していたとして、「家具の入力フォームを編集するメソッド」があったとして、別機能として「販売管理系の入力フォームを編集するメソッド」が後から追加される場合に「家具の入力フォームと似た作りになってるからそちらのメソッドを呼んだ方がDRYになるから呼ぼう」という考え方ではNGになります。将来的に、「家具の入力フォームだけ機能改修が入った場合」に「販売管理系のフォームに影響がないか」を把握しておかなければならないためです。

単一責任を守った上での共通化とは?

なので、「ビジネスロジックを共通化する」のは仕様変更の影響を受けてしまうので基本的にはNGです。

単一責任を守った上で共通化するのであれば、例えば、フォームの中のテキストボックスだとか小さい粒度をバリューオブジェクト化して共通化していくなどが良いでしょう。そういった小さい粒度の要素は仕様変更の影響を受けにくいためです。(テキストボックスクラスを作って保持する状態のバリデーションロジックなどは共通化できると思います。)

フラグを渡して、条件分岐させるのはどうか

フラグを渡して共通処理の中で分岐させるのも以下の理由からNGになります。

  • 条件分岐で処理が肥大化して可読性が下がる。
  • 分岐があるとメソッド名から何をやっているかすぐに処理内容を類推することができなくなる。

できるだけ分岐を使わず一つの仕様は単一のクラスで処理するような実装にしましょう。

例2

「受注画面クラス」があった場合以下のような処理を全て同じクラスに記述してしまうと単一責任の原則に反します。

  • 受注データの入力
  • 受注データのDB登録
  • 登録済みデータのメール送信

メール送信処理にBCCも追加する修正を加えるとなった際に、「受注画面クラスを変更」しなければなりません。

修正例

以下のように分けること。

  • 受注画面クラス
  • 受注データアクセスクラス(DBアクセス)
  • メール送信クラス

よくある分け方

この三つに分けるのもよくありがちなパターンだと思いますが、これも「単一責任の原則」を考慮した上での分け方になります。

  • 画面
  • ビジネスロジック
  • データアクセス

画面

ビジネスロジック

頻繁に変化する。

データアクセス

インフラが変わった場合などに変更することになるだけで、頻繁には変化しない。

その他デメリット

ある責務を期待してそのクラスを利用しようとしたときに、期待していない機能までついてきてクラスの再利用性が低くなる。

スポンサーリンク
  • 2022 03.26
  • miyabisan2
  • 1件のコメント
  • オブジェクト指向
  • Tweets Twitter
  • このエントリーをはてなブックマークに追加
  • LINEで送る

関連記事

  1. 2018 05.19

    【設計】クラス設計(オブジェクト指向設計)の基本(保守性、再利用性の高いソースコードを書くには?)

  2. 2018 05.12

    【GoFのデザインパターン】「Singleton(シングルトン)」ってどんなパターン?、注意点なども。

  3. 2021 08.28

    【オブジェクト指向】「オープン・クローズドの原則」とは

  4. 2018 04.30

    【Java】オブジェクト指向:継承の考え方や注意点

  5. 2022 05.21

    【オブジェクト指向】「インターフェース分離の原則」について

  6. 2022 03.26

    【オブジェクト指向】「集約」、「継承」、「委譲」の使い分け

  • コメント ( 0 )
  • トラックバック ( 0 )
  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

返信をキャンセルする。

【React】「CSSの選択肢」(Pure CSS、C…

【オブジェクト指向】「集約」、「継承」、「委譲」の使い…

RETURN TOP

著者プロフィール

エンジニア歴10年で過去に業務系、Webデザイン、インフラ系なども経験あります。現在はWeb系でフロントエンド開発中心です。

詳細なプロフィールはこちら

スポンサーリンク

カテゴリー

  • Android
  • AngularJS
  • API
  • AWS
  • C++
  • CSS
  • C言語
  • DDD
  • DevOps
  • Django
  • Docker
  • Figma
  • Git
  • GitLab
  • GraphQL
  • Hasura
  • Java
  • JavaScript
  • Kubernetes
  • Laravel
  • linux
  • MySQL
  • Next.js
  • nginx
  • Node.js
  • NoSQL
  • Nuxt.js
  • Oracle
  • PHP
  • Python
  • React
  • Redux
  • Rspec
  • Ruby
  • Ruby on Rails
  • Sass
  • Spring Framework
  • SQL
  • TypeScript
  • Unity
  • Vue.js
  • Webサービス開発
  • Webデザイン
  • Web技術
  • インフラ
  • オブジェクト指向
  • システム開発
  • セキュリティ
  • その他
  • データベース
  • デザインパターン
  • テスト
  • ネットワーク
  • プログラミング全般
  • マイクロサービス
  • マイクロソフト系技術
  • マルチメディア
  • リファクタリング
  • 副業
  • 未分類
  • 業務知識
  • 生成AI
  • 設計
  • 関数型言語
RETURN TOP

Copyright ©  プログラミングマガジン | プライバシーポリシー