@nqounetです。
前回は、すべてのハンドラーがrunメソッドを持つという約束をMoo::Roleのrequiresで定義し、インターフェースを作りました。
今回は、ハンドラーを保持して処理を振り分けるディスパッチャークラスを作ります。このクラスが「司令塔」として働き、適切なハンドラーに処理を委ねます。
問題:ハンドラーを誰が管理するのか
前回までにListHandlerやFormHandlerなどのハンドラークラスを作りました。でも、これらのハンドラーを管理して、適切なタイミングで呼び出す役割は誰が担うのでしょうか?
今のところ、利用側のコードで直接ハンドラーを生成して呼び出しています。
| |
一見シンプルですが、アプリケーションが大きくなると問題が生じます。
- どのハンドラーを使うか判断するロジックがあちこちに散らばる
- ハンドラーの生成と呼び出しが分離されておらず、テストしにくい
- 新しいハンドラーを追加するたびに、呼び出し側も変更が必要
ハンドラーを一元管理して、処理を振り分ける「司令塔」が必要です。
解決策:ディスパッチャークラスを作る
ハンドラーを保持し、処理を振り分ける専用のクラスを作りましょう。前シリーズの第11回で学んだ「委譲(handles)」を活用すると、ディスパッチャーがハンドラーのメソッドをスムーズに呼び出せます。
flowchart TB
subgraph Dispatcher["Dispatcher(司令塔)"]
H["has handler"]
D["dispatch()"]
end
D -->|"handler->run()"| Handler
subgraph Handler["ハンドラー"]
R["run()"]
end
Dispatcherクラスの作成
まずはシンプルなDispatcherクラスを作ります。
| |
has handlerでハンドラーオブジェクトを保持し、dispatchメソッドでそのハンドラーのrunメソッドを呼び出します。Dispatcherが司令塔として「どのハンドラーに処理を任せるか」を管理する設計です。
handlesを使った委譲
dispatchメソッドを書く代わりに、handlesを使えばさらにシンプルになります。
| |
handles => ['run']によって、$dispatcher->run()と呼び出すと、内部で$dispatcher->handler->run()が実行されます。Dispatcherに渡すハンドラーを変えるだけで、異なる処理が実行されるのがポイントです。
まとめ
- ハンドラーを管理する司令塔としてDispatcherクラスを作成した
has handlerでハンドラーを保持し、dispatchメソッドで処理を振り分けるhandlesを使えばハンドラーのメソッドに直接委譲できる- Dispatcherに渡すハンドラーを変えれば、実行される処理も変わる
次回予告
次回は、実行時にハンドラーを動的に切り替える機能を追加します。is => 'rw'を使って、柔軟にハンドラーを差し替えられるようにしていきましょう。

