Madogiwa Blog

主に技術系の学習メモに使っていきます。

Rubyで学オブジェクト指向 SOLID原則「単一責任の原則(Single responsibility principle)」

Clean Architecture 達人に学ぶソフトウェアの構造と設計を読んで、オブジェクト指向の原則について学びがあったので、Rubyのコード例と共に内容を整理してみました。

Clean Architecture 達人に学ぶソフトウェアの構造と設計

Clean Architecture 達人に学ぶソフトウェアの構造と設計

※私の学びのメモなので理解が間違ってる可能性があります、間違ってたらすいません🙇‍♂️

単一責任の原則(Single responsibility principle)とは?

1つのクラスは1つだけの責任を持たなければならない。すなわち、ソフトウェアの仕様の一部分を変更したときには、それにより影響を受ける仕様は、そのクラスの仕様でなければならない。 https://ja.wikipedia.org/wiki/SOLID

この原則は、書いてあるとおり1つのクラスでは1つのことだけに関心を持ち、振る舞いが変化する場合は対象のClassに閉じてなければいけないという原則ですね。

単一責任の原則の例とコード

単一責任の原則を意識できていないコードと例

例えば下記のような社員を管理するEmployeeクラスがあったとします。

class Employee
  def initialize
    # build employeer object.
  end

  def work
    progress # do work for all employee.
    if manager? 
      # do only manager.
    end
    if member?
      # do only member.
    end
  end
end

上記Classにはどのような仕様変更が発生し得るでしょうか?Employeeクラスには、管理者、メンバについての振る舞いを定義しています。そのため以下ような管理者、メンバに関する仕様変更が発生することが予測できます。

  • 管理者の管理業務の振る舞いに変更を加えてほしい。
  • 管理者に部下の一覧をプロパティ(subordinates)として追加したい。
  • メンバの報告業務の振る舞いを変更を加えてほしい。
  • メンバに上司をプロパティ(manager)として追加したい。

このままでは様々な仕様変更が、このクラスに発生してどんどん肥大化していき見通しが悪くなってしまいそうですね。。。

単一責任の原則を意識してリファクタリングしてみる

単一責任の原則は、先程の変更理由の関心単位に1つのClassにして凝集性を担保しましょうという原則です。

凝集性
モジュール内のソースコードが特定の機能を提供すべく如何に協調しているかを表す度合い https://ja.wikipedia.org/wiki/%E5%87%9D%E9%9B%86%E5%BA%A6

先程の先程の変更利用にそれぞれ、何に関する変更なのか記載してみました。

  • 管理者の管理業務の振る舞いに変更を加えてほしい。→ 管理者に関する変更
  • 管理者に部下の一覧をプロパティ(subordinates)として追加したい。→ 管理者に関する変更
  • メンバの報告業務の振る舞いを変更を加えてほしい。→ メンバに関する変更
  • メンバに上司をプロパティ(manager)として追加したい。→ メンバに関する変更

実際に単一責任の原則を意識して変更理由の単位でコードを修正すると下記のような形になるのかなと思います。

class Manager
  def initialize(attributes)
    # assign attributes.
    @subordinates = attributes[:subordinates]
  end

  def work
    progress
    # do only manager.
  end
end

class Member
  def initialize(attributes)
    # assign attributes.
    @manager = attributes[:manager]
  end

  def work
    progress
    # do only member.
  end
end

管理者、メンバそれぞれをClassに切り出すことにより、if文が無くなり見通しが良くなっただけでなく、管理者の変更の場合はManagerを変更するといった変更箇所が明確になり迷いにくくなっています。また変更理由によって変更するクラスがことなるため、コードの競合も防げそうですね🙌

おわりに

今回はオブジェクト指向のSLID原則「単一責任の原則(Single responsibility principle)」について自分の理解をRubyのコード例とともに説明してみました。今までSOLIDの原則はキーワードは知っているつもりでいましたが、実際に書籍で学んでアウトプットすると、より理解が深まりますね。

次回は「開放閉鎖の原則(Open–closed principle)」について書いてみようかと思います 🙇‍♂️

参考

Clean Architecture 達人に学ぶソフトウェアの構造と設計

Clean Architecture 達人に学ぶソフトウェアの構造と設計

postd.cc