設計思想
設計判断の原則と考え方。
3つの原則
Naifyの設計判断は、次の3原則に集約されます。
原則1:コードを読めばわかる
暗黙挙動より明示を優先します。処理の流れはソースコードを上から読むだけで追跡できる形を目指します。
原則2:責務を明確にする
Routerはルーティング、Controllerはユースケースの調停、BaseControllerはフロー制御と共通前処理に寄せます。何がどこにあるかを役割で探せるようにします。
原則3:PHPがわかれば使える
独自DSLや固有構文を増やしすぎません。標準的なPHPのクラス、関数、インターフェースを理解していれば読み始められるようにします。
明示的な初期化
依存関係が見える組み立て
責務境界が見えるディレクトリ設計
マジックメソッド依存
オートワイヤリング前提
属性での暗黙ルーティング
ミドルウェア論
NaifyはPSR-15相当のミドルウェア基盤を持っていますが、そこへ積極的にビジネスロジックを載せる方針は取っていません。MVCの中で整理できるものはMVCの中に残します。
積極採用しない理由
- MVCのライフサイクルで大半の処理が収まる
- ミドルウェアへ業務ロジックを書き始めると、責務の所在が曖昧になりやすい
- 実行順の追跡コストが増えやすい
- FWごとのセッションや設定に依存し始めると、PSR準拠のメリットが薄くなる
| 推奨用途 | MVCに置きたいもの |
|---|---|
|
CORSヘッダー付与 セキュリティヘッダー アクセスログ |
認証・認可の判定 業務ロジックの分岐 画面やJSONの内容生成 |
BaseController::onActionBefore() に寄せる方が、プロジェクトの流れを追いやすいです。
PSRとの疎結合
NaifyはPSRを参考にしていますが、アプリ開発の主軸はPSR middlewareに置いていません。
NaifyはPSR-7のRequest / Responseを内部で扱っていますが、アプリコードから直接触ることは標準にしていません。代わりに RequestContext を標準の窓口にしています。
これにより、Controllerは getParam() や getUrlParam() のような単純なAPIに集中できます。PSR実装の差し替えもアプリコードへ波及しにくいです。
//普段のコード
$id = $this->context->getUrlParam('id');
$name = $this->context->getParam('name', '');
//必要なときだけPSRを取り出す
$request = $this->context->getPsrRequest();
$response = $this->context->getPsrResponse();
echoを標準にする理由
Naifyのデフォルトは、Controllerが自分で出力する方式です。Responseオブジェクトを複数レイヤで加工するより、描画やJSON出力の責務をController側へ寄せた方が、読み順が崩れにくいです。
Initial Architecture Lock
設計を文書だけで終わらせず、コード構造に固定するという考え方。特にBaseControllerは、そのプロジェクトで「どこに何を書くか」を最初に固定する役目を持ちます。
とりあえず作る
あとで整理する
ルールが散らばる
BaseControllerに落とす
全員が同じ入口を使う
構造が崩れにくい
BaseController戦略
BaseControllerは1つの神クラスにまとめるより、用途ごとに薄く分けた方が読みやすいです。ここで大切なのは、共通前処理の入口を固定しつつ、責務を抱え込みすぎないことです。
- Web用: Twig出力や画面向け共通処理
- API用: JSON出力やAPI向け共通処理
- 認証済み用:認証済み画面だけが持つ前処理