本稿ではPHPでMiddlewareパターンの設計と実装を紹介する。本稿で扱うMiddlewareパターンは、Interpreterパターンの変種であり、典型的なMiddlewareパターンではない。典型的なMiddlewareパターンの設計および実装は❄️PHPでMiddlewareパターンを実装する方法を参照。
Middlewareパターンとは
Middlewareパターンの目的は、「ミドルウェア」と呼ばれるガワの処理で核となるハンドラを包むことで、プログラム本来の振る舞いを拡張可能にすること。MVCウェブフレームワークでは、コントローラの入出力となるHTTPリクエストやレスポンスをアプリケーション全体で統一的に加工する用途などに採用されている。
ミドルウェアができることは次の3つ:
- クライアントコードとハンドラの間に割って入り、入力を加工する
- ハンドラとクライアントコードの間に割って入り、出力を加工する
- クライアントコードとハンドラの間に割って入り、入力がハンドラに届く前に、早期に出力を返す
Middlewareパターン(Interpreterパターン風)
本稿で扱うMiddlewareパターンは上記の機能うち2と3がない。厳密にはInterpreterパターンと言える。そのぶん、典型的なMiddlewareパターンよりも単純になっている。
設計
実装
interface Middleware
{
public function call(int $input): int;
}
final class MiddlewareChain implements Middleware
{
/**
* @var Middleware[]
*/
private $middlewares = [];
public function add(Middleware $middleware): void
{
$this->middlewares[] = $middleware;
}
public function call(int $input): int
{
foreach ($this->middlewares as $middleware) {
$input = $middleware->call($input);
}
return $input;
}
}
final class IncrementMiddleware implements Middleware
{
public function call(int $input): int
{
return $input + 1;
}
}
final class TwiceMiddleware implements Middleware
{
public function call(int $input): int
{
return $input * 2;
}
}
$chain = new MiddlewareChain();
$chain->add(new IncrementMiddleware);
$chain->add(new TwiceMiddleware);
assert($chain->call(1) === (1 + 1) * 2);
assert($chain->call(2) === (2 + 1) * 2);
assert($chain->call(3) === (3 + 1) * 2);
よかったらRTお願いします !
✏️書いた → PHPでMiddlewareパターンを実装する方法(Interpreterパターン風) - Qiita https://t.co/RVTCHSr3K2 pic.twitter.com/h2WzfpsYxH
— suin (@suin) 2018年4月18日