Validation をどこでやるか問題は、丁度タイムリーに悩んだりしてたところで、下記のブログを目にした。コメント書こうと思って MovableType でログインしたのに「権限エラー」とかなったからここに書く。
俺も最初は RoR とかみたく、Model や ORM に書くべきかなぁ、なんて考えてたんだが、結論から言うと自分の場合は今回は Validator Class を切り出すことにした。(丁度社内のオレオレFWを実装してた)
というのも、たしかに上記ブログに書いてあるように
DBを使わないケースならばいわゆるFomrValidator::*を使ってControllerでやればいいのですが、Modelを経由するようなアプリだとControllerだけじゃ不安よねぇ〜、Modelだけ使う時もあるし、Model単体のテストで再現出来ないよね〜なんて思ってます。
ORMにValidation機構を持たせる – ゆーすけべー日記
というパターンもあって、やっぱり Model に書くのが定石だとは思うわけだが、逆に言えば Presentation層だけのテストもしにくいじゃん、なんて思ったりして。さらに言えば、Presentation層特有のチェックはどこに書くんじゃラホイ?的なことも。(たとえば、ドメインやサービス的には問題ないけど、Usability的に検索条件は1つ以上は入れようね的なチェックとか)
切り出した Validator クラスは、DI もしくはオレオレFWの命名の規約により、
C → 参照 → Validator ← 参照 ← Model
とする感じ。
でも実はまだふにゃふにゃしてたり。というのも、ドメインだけ意識すれば最終的に Model に Validation を実装すればデータが潰れないという意味では前述のとおりなのだけれど、結局は(Server Layer的な意味での)3層を意識すると、JavaScript でチェックできるときはチェックしてあげるほうが親切じゃん?ってところが。(別に JavaScript じゃなくてもいいんだけど)
つまり、View から Controller 経由で API として Validation 定義を取得するようにしよかとか、もしくは View を Response する段階で Validation の定義を JavaScript や JSON に変換するような Filter かまして Client 側の FW などと統合しようかとかその辺がモヤモヤ。
もちろん、JavaScript の Validation Library は独自に存在するのだけれど、大抵それは JavaScript 独自の FW になっていて、Server 再度で定義したチェックを利用してチェックできるようなものは見当たらないので、その辺りを統一的に書きたい。(特に業務系アプリなんて大量の画面作るときに、チェックを二重に書くのは無駄じゃん?)
色々書いたけれど、冒頭の Entry は Perl で既存の Module を利用しての実装について悩んでるようだから少し(というかだいぶ)ずれちゃってるかもしれない。
ただ、Validation の機構ってのは大規模になると、MVC を統括的に管理する新たな位置づけとして設計しないと、効率的なコードにならない気がしなくもない。入力検証だけでなく、データ保存後の整合性なんかも含めて考えたら尚更。
ASP.net? のような、WindowsForm 系はその辺りを各コントロールに書いたりして、Client側の VとServer側の C でのチェックが1箇所でかけるようにはなっているけど、Model という意味では FW 的に統合されていない。(と思う)
というわけで、Validation をどこに書くか問題というのは、悩ましい問題なのである。