はじめに
作った動機を箇条書きにすると、こんな感じです。
- どうしても長くなってしまう操作・処理がある
- いわゆる手続き型プログラミング
- 例えば、イベントリスナー
- 何かの前処理や後処理を一箇所で書けて、かつ呼び出しも自動的に行われるから便利
- 目的ごとに、複数のリスナーを用意しているが、それでもビジネス要件によってやることは増える
- 例えば、コマンド
- バッチ処理など、手動または自動で実行される処理をCUIで呼び出すことができて便利
- オプショナルの引数が増えるなどして、少しずつ処理が複雑になっていく
- とにもかくにも、いったん何かの単位でコードを分割したい
最初はそんな動機で何か既にある素晴らしいライブラリがないか探しました。
league/pipeline
を使うだけで良さそうに思えた
league/pipeline を見たときは、「ああ、これだよ。これでいいじゃん」って思いました。
しかし、結論からいうと、今回は車輪の再発明覚悟で自作することにしました。
今回、一度、構築したパイプライン(callableの配列)に、コールバック(callable)を後から差し込みたかったのですが、そのインターフェイスがなかったというのが最大のポイントでした。
league/pipeline
を参考にしつつも、自分なりにライブラリを作ることに
自作するにあたって、league/pipeline
を真似した部分とそうでない部分があります。
league/pipeline
を真似した部分
-
callableの配列を順番に処理する
-
callable
であれば良いので、__invokeを実装したクラスでもOK
-
-
Be immutable.
防御的コピーを活用して、状態が不変(イミュータブル)になるようにしました
league/pipeline
を真似しなかった部分
-
callable
の配列に追加する際、配列のキー(int型)を指定できるようにした- 配列は
ksort
によって並べ替えられるので、後からcallable
を任意の位置に挿入することが可能に
- 配列は
-
PipelineBuilder
のかわりに、Pipes
を作成し、Pipeline
はコンストラクタでPipes
を受け取るようにした-
Pipeline
のコンストラクタでarray
を受け取っていたのでは、callable
以外のものを突っ込まれる可能性があるので
-
-
ProcessorInterface
でProcessor
を入れ替えられるようになっているが、用途が思いつかないので、採用しなかった - コールバック(callable)の引数は、
array $payload
ではなく、Context
オブジェクトを渡すようにした -
Status
をisStopped
に変更することで、処理を途中でやめることができるようにした
ということで公開しました
小さいライブラリなので、Scrutinizer-ci
のスコア10点満点、カバレッジ100%にして公開しました。
おわりに
お手伝いしている現場でも実際に使ってみて、長い処理をひとまず分割していけたらと思います。
league/pipeline
がこれを真似してくれたら、嬉しいですね。
実際、本番で動くようになったら、様子をみて、v1.0.0にしたいと思います。
ではでは。