##概要
要求を受信するフクスのオブジェクトをチェーン状につなぎ、あるオブジェクトがその要求を処理するまでチェーンに沿って要求を渡していくパターン
以下の5種類のクラスからなる
- Handlerクラス(要求を処理するためのインターフェイスを定義)
- ConcreteHandlerクラス(要求の中で担当するものについての処理を実装、担当外の要求はsuccessorに転送する)
- Clientクラス(チェーンの中にある2.に要求を出す)
##具体例と実装
会社内での業務確認を例にすると、
上記1~3はそれぞれ
- 社員クラス(Staffクラス、確認内容のチェックと回答、部下社員への確認指示を行う)
- 課長クラス、部長クラス、メンバークラス(SectionManagerクラス、Managerクラス、Memgerクラス、自分の担当範囲の業務確認内容かを判断し、回答、あるいは確認指示を行う)
- 社長クラス(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)
##メリット
- 要求を処理する相手を知る必要が無いため、オブジェクトの結合度が低くなる
- チェーンの中にオブジェクトを追加したり変更したりすることで、オブジェクトの処理に対する責任の割り振りを柔軟に変更出来る
##まとめ
処理を行う責任を持ったオブジェクトを連ねて、そのなかのどこかの段階でいずれかのオブジェクトが処理を行うパターン