LoginSignup
1
1

More than 5 years have passed since last update.

【デザインパターン】 Chain Of Resposibilityパターン

Posted at

概要

要求を受信するフクスのオブジェクトをチェーン状につなぎ、あるオブジェクトがその要求を処理するまでチェーンに沿って要求を渡していくパターン

以下の5種類のクラスからなる
1. Handlerクラス(要求を処理するためのインターフェイスを定義)
2. ConcreteHandlerクラス(要求の中で担当するものについての処理を実装、担当外の要求はsuccessorに転送する)
3. Clientクラス(チェーンの中にある2.に要求を出す)

具体例と実装

会社内での業務確認を例にすると、

上記1~3はそれぞれ

  1. 社員クラス(Staffクラス、確認内容のチェックと回答、部下社員への確認指示を行う)
  2. 課長クラス、部長クラス、メンバークラス(SectionManagerクラス、Managerクラス、Memgerクラス、自分の担当範囲の業務確認内容かを判断し、回答、あるいは確認指示を行う)
  3. 社長クラス(Presidentクラス、確認事項を投げる)

が対応する。
コードの詳細は以下

staff.rb
class Staff
  def initialize
    @next_staff = nil
  end

  def set_next_staff(staff)
    @next_staff = staff
  end

  def handle_request(request)
    if check_request(request)
      confirm_request(request)
    elsif(@next_staff)
      next_staff.handle_request(request)
    end
  end
end
section_manager.rb
class SectionManager < Staff
  def check_request(request)
    # 課長に確認可能な内容か判断
  end

  def confirm_request(request)
    # 確認して、確認結果を返す
  end
end
manager.rb
class Manager < Staff
  def check_request(request)
    # 部長に確認可能な内容か判断
  end

  def confirm_request(request)
    # 確認して、確認結果を返す
  end
end
member.rb
class Member < Staff
  def check_request(request)
    true # どんな内容でも確認!
  end

  def confirm_request(request)
    # 確認して、確認結果を返す
  end
end
president.rb
section_manager = SectionManager.new
manager = Manager.new
member = Member.new
section_manager.set_next_staff(manager)
manager.set_next_staff(member)

section_manager.handle_request(request)

メリット

  • 要求を処理する相手を知る必要が無いため、オブジェクトの結合度が低くなる
  • チェーンの中にオブジェクトを追加したり変更したりすることで、オブジェクトの処理に対する責任の割り振りを柔軟に変更出来る

まとめ

処理を行う責任を持ったオブジェクトを連ねて、そのなかのどこかの段階でいずれかのオブジェクトが処理を行うパターン

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1