Catalyst から Model を切り離せ - MVC の M のあるべき姿  - Dann [email_address]
アジェンダ <ul><li>WAF における MVC と WAF と M の関係 </li></ul><ul><li>Catalyst(WAF) から M を切り離す方法 </li></ul><ul><li>MVC の M を構築するためのアー...
WAF における MVC と WAF と M の関係
WAF の役割 <ul><li>WAF は基本的に Web/Http の世界の仕事をする </li></ul><ul><ul><li>セッション管理 </li></ul></ul><ul><ul><li>認証処理 </li></ul></ul>...
WAF の役割でないこと <ul><li>モデルの管理 </li></ul><ul><ul><li>モデルのビジネスロジック </li></ul></ul><ul><ul><li>モデルの Caching の機構 </li></ul></ul>...
WAF と Model の関係のあるべき姿は? <ul><li>基本は、 Model は Web の世界からは切り離されていること </li></ul><ul><li>MVC の M は  POPO(Plain Old Perl Object)...
M を WAF から切り離すべき理由 <ul><li>Testability が向上する </li></ul><ul><ul><li>モデルの Unit Test が Catalyst を使わずに可能に </li></ul></ul><ul><...
とはいっても、 WAF では一部 M を知る必要がある。 どうするか?
Catalyst(VC) と Model(M) の関係別の Model の切り離し方
M と VC の機能の共有関係 <ul><li>(a) M と VC 間に機能共有が必要でない場合 </li></ul><ul><li>(b) M,V,C の全てで共有したい機能がある場合 </li></ul><ul><ul><li>Ex)  ...
<ul><li>M でしか必要のない機能の場合 </li></ul><ul><li>モデルの切り離し方 </li></ul><ul><ul><li>Catalyst の Model にせず 、 POPO だけを使う </li></ul></ul...
(b) WAF と APP( モデル ) で機能 を共有したい場合 <ul><li>例えば国際化 </li></ul><ul><ul><li>V でも C でも国際化したい  e.g (c.loc) </li></ul></ul><ul><ul...
(b) のパターン POPO Model Catalyst Controller Catalyst View MyApp::I18N Catalyst Plugin::I18Nx C M V
(c) WAF の一部でモデル が必要な場合 <ul><li>例えば、認証の機構 </li></ul><ul><ul><li>プラグイン側では認証の仕組みが必要で一部モデルが必要。モデル側では認証の仕組みは不要というケース。 </li></ul...
(c)  のパターン POPO User Catalyst ::Model::Adaptor Catalyst::Plugin::Authentication ::Store::DBIC   M
MVC の M を構築する アーキテクチャ
Domain Logic Patterns <ul><li>Domain Model(+Service Layer) </li></ul><ul><ul><li>Service(workflow logic) </li></ul></ul><u...
Service Layer + Domain Model  <ul><li>「モデル」を Service と Domain Model に分ける </li></ul><ul><li>Service Layer </li></ul><ul><ul...
多くの Web アプリケーション における一つの仮定 <ul><li>複雑なビジネスロジックは少ない </li></ul><ul><li>CRUD の処理をすることのほうが多い </li></ul><ul><li>CLI が管理用スクリプトとし...
仮定に基づいた Domain model と Service Layer への疑問 <ul><li>DB の構造を見せないリッチな OO なドメインモデルが必要? </li></ul><ul><ul><li>多くの場合不要。無駄に Domain...
Service Layer + Domain Model の現実解 <ul><li>Service </li></ul><ul><ul><li>アプリケーションロジック ( ワークフローロジック)を書く </li></ul></ul><ul><...
Catalyst にマッピングすると POPO Service POPO Models (With DBIC) Catalyst Controller Catalyst View POPO Models (With DBIC) M これが一番シ...
モデル( Service+Domain Model) を構築するための色々な要求 <ul><li>POPO モデル毎に簡単な設定情報を渡したい </li></ul><ul><li>POPO モデルを簡単に WAF から参照したい </li></...
DI コンテナ + POPO Model のアーキテクチャ POPO Service POPO Model (Schema::*  など参照 ) Catalyst Controller Catalyst View DIコンテナ Catalyst...
DI コンテナを利用したモデル構築 <ul><li>DI コンテナ利用の利点 </li></ul><ul><ul><li>モデルは DI コンテナで Wiring されるため、モデルが Catalyst の context に依存することが無く...
まとめ <ul><li>Catalyst は WAF としては必要十分 </li></ul><ul><li>モデル (Service, Domain Model) について </li></ul><ul><ul><li>モデルは WAF から切り...
ご清聴ありがとうございました  !
付録
Service Layer+Domain Model の構築に必要な仕組み (Application Framework としての仕組み) <ul><li>モデルを Wiring ・設定情報を Inject する仕組み </li></ul><u...
モデルを Catalyst から 切り離すのに実装が必要なもの <ul><li>ConfigLoader </li></ul><ul><li>Logger </li></ul><ul><li>Caching </li></ul><ul><li>...
Upcoming SlideShare
Loading in...5
×

Separate Model from Catalyst

9,392

Published on

catalystcon1

Published in: Technology
0 Comments
7 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
9,392
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
21
Comments
0
Likes
7
Embeds 0
No embeds

No notes for slide

Separate Model from Catalyst

  1. 1. Catalyst から Model を切り離せ - MVC の M のあるべき姿 - Dann [email_address]
  2. 2. アジェンダ <ul><li>WAF における MVC と WAF と M の関係 </li></ul><ul><li>Catalyst(WAF) から M を切り離す方法 </li></ul><ul><li>MVC の M を構築するためのアーキテクチャ </li></ul>
  3. 3. WAF における MVC と WAF と M の関係
  4. 4. WAF の役割 <ul><li>WAF は基本的に Web/Http の世界の仕事をする </li></ul><ul><ul><li>セッション管理 </li></ul></ul><ul><ul><li>認証処理 </li></ul></ul><ul><ul><li>URL ディスパッチャ </li></ul></ul><ul><ul><li>フォームバリデーション </li></ul></ul><ul><li>Controller としての役割 </li></ul><ul><ul><li>M と V のノリとしての役割 </li></ul></ul><ul><ul><li>モデルへ処理の委譲 </li></ul></ul><ul><ul><li>モデルの処理結果を View にフォワード </li></ul></ul>
  5. 5. WAF の役割でないこと <ul><li>モデルの管理 </li></ul><ul><ul><li>モデルのビジネスロジック </li></ul></ul><ul><ul><li>モデルの Caching の機構 </li></ul></ul><ul><ul><li>Etc.. </li></ul></ul><ul><li>Catalyst で良くない点 </li></ul><ul><ul><li>Catalyst::Model::* </li></ul></ul><ul><ul><ul><li>M が Catalyst に依存している </li></ul></ul></ul><ul><ul><li>Model をプラガブルに拡張するのは、 AF の役割 </li></ul></ul>
  6. 6. WAF と Model の関係のあるべき姿は? <ul><li>基本は、 Model は Web の世界からは切り離されていること </li></ul><ul><li>MVC の M は POPO(Plain Old Perl Object) で構成する </li></ul><ul><li>Why ? </li></ul>
  7. 7. M を WAF から切り離すべき理由 <ul><li>Testability が向上する </li></ul><ul><ul><li>モデルの Unit Test が Catalyst を使わずに可能に </li></ul></ul><ul><ul><li>テストの実行速度が早くなる </li></ul></ul><ul><li>Web のコンテキスト以外での再利用 が可能になる </li></ul>POPO Service POPO Model (Schema::* など) CLI (App::CLI, App::Cmd) WebAPI (Catalyst::Controller::Resources) Catalyst::Controller M
  8. 8. とはいっても、 WAF では一部 M を知る必要がある。 どうするか?
  9. 9. Catalyst(VC) と Model(M) の関係別の Model の切り離し方
  10. 10. M と VC の機能の共有関係 <ul><li>(a) M と VC 間に機能共有が必要でない場合 </li></ul><ul><li>(b) M,V,C の全てで共有したい機能がある場合 </li></ul><ul><ul><li>Ex) 国際化の機構( Controller 、 View 、 POPO Model どこでも必要) </li></ul></ul><ul><li>( c ) V, C の一部で M が必要な場合 </li></ul><ul><ul><li>Ex) 認証の機構 </li></ul></ul><ul><ul><li>M のロジックはいらないが、データは必要 </li></ul></ul>このパターン別に、モデルの切り離し方、 VC との繋ぎ方がある。
  11. 11. <ul><li>M でしか必要のない機能の場合 </li></ul><ul><li>モデルの切り離し方 </li></ul><ul><ul><li>Catalyst の Model にせず 、 POPO だけを使う </li></ul></ul>POPO Service POPO Model Catalyst Controller Catalyst View M V C
  12. 12. (b) WAF と APP( モデル ) で機能 を共有したい場合 <ul><li>例えば国際化 </li></ul><ul><ul><li>V でも C でも国際化したい e.g (c.loc) </li></ul></ul><ul><ul><li>M でも国際化したい eg. loc(‘message’) </li></ul></ul><ul><li>モデルの切り離し方 </li></ul><ul><ul><li>アプリケーション (POPO Model) 側で共通の機能 ( 国際化)を実装 し、プラグインでアプリケーションの機能を参照する </li></ul></ul><ul><ul><ul><li>Plugin::I18N --> MyApp::I18N </li></ul></ul></ul><ul><ul><li>国際化方法 </li></ul></ul><ul><ul><ul><li>POPO Model(MyApp::Model::Hoge) からは MyApp::I18N で国際化 . E.g) loc </li></ul></ul></ul><ul><ul><ul><li>View では、 Plugin::I18N で国際化 . E.g) c.loc </li></ul></ul></ul>
  13. 13. (b) のパターン POPO Model Catalyst Controller Catalyst View MyApp::I18N Catalyst Plugin::I18Nx C M V
  14. 14. (c) WAF の一部でモデル が必要な場合 <ul><li>例えば、認証の機構 </li></ul><ul><ul><li>プラグイン側では認証の仕組みが必要で一部モデルが必要。モデル側では認証の仕組みは不要というケース。 </li></ul></ul><ul><ul><li>ユーザークラスは Catalyst のモデルじゃないと Catalyst の Plugin から参照が… </li></ul></ul><ul><li>モデルの切り離し方 </li></ul><ul><ul><li>Catalyst(WAF) の世界にモデルを閉じ込めるのがいい </li></ul></ul><ul><ul><li>Catalyst::Model::Adaptor が最適 </li></ul></ul>
  15. 15. (c) のパターン POPO User Catalyst ::Model::Adaptor Catalyst::Plugin::Authentication ::Store::DBIC M
  16. 16. MVC の M を構築する アーキテクチャ
  17. 17. Domain Logic Patterns <ul><li>Domain Model(+Service Layer) </li></ul><ul><ul><li>Service(workflow logic) </li></ul></ul><ul><ul><li>Domain Model(domain logic) </li></ul></ul><ul><ul><li>Logic とデータは同じところに </li></ul></ul><ul><ul><li>ask ではなく、 tell. </li></ul></ul><ul><li>Transaction Script </li></ul><ul><ul><li>Unit of Work が 1 メソッド </li></ul></ul><ul><ul><li>Logic とデータの分離 </li></ul></ul><ul><ul><li>Ask のモデル </li></ul></ul><ul><li>Table Module </li></ul>※ 詳しくは PofEAA 参照
  18. 18. Service Layer + Domain Model <ul><li>「モデル」を Service と Domain Model に分ける </li></ul><ul><li>Service Layer </li></ul><ul><ul><li>Application logic(Workflow logic) </li></ul></ul><ul><ul><ul><li>Domain Model に対して問題を解決するよう処理を委譲 </li></ul></ul></ul><ul><ul><li>Publish するインターフェースの明示 </li></ul></ul><ul><ul><ul><li>Controller に見せる処理の明示 </li></ul></ul></ul><ul><ul><li>トランザクション境界 </li></ul></ul><ul><li>Domain Model </li></ul><ul><ul><li>Domain logic </li></ul></ul><ul><ul><li>問題領域のロジックは Domain Model に </li></ul></ul><ul><ul><li>ここに主にロジックを記述 </li></ul></ul>
  19. 19. 多くの Web アプリケーション における一つの仮定 <ul><li>複雑なビジネスロジックは少ない </li></ul><ul><li>CRUD の処理をすることのほうが多い </li></ul><ul><li>CLI が管理用スクリプトとして必要になるケースは多い </li></ul><ul><li>重い処理を Job Queue に委譲することは割にある </li></ul>
  20. 20. 仮定に基づいた Domain model と Service Layer への疑問 <ul><li>DB の構造を見せないリッチな OO なドメインモデルが必要? </li></ul><ul><ul><li>多くの場合不要。無駄に Domain Model をラップすることになる </li></ul></ul><ul><ul><li>DB だけの場合、 Domain Model=ER モデル で十分 </li></ul></ul><ul><li>ドメインモデルでは、 DB に依存しない抽象化が必要 ? </li></ul><ul><ul><li>DB しか使わなければ、抽象化不要 </li></ul></ul><ul><li>常に Controller は Service Layer を介する必要あり? </li></ul><ul><ul><li>そんなことはない。直接 Domain Model を触ってもよい。 </li></ul></ul><ul><ul><li>1 つのドメインモデルのロジックしか必要ないこともある </li></ul></ul>
  21. 21. Service Layer + Domain Model の現実解 <ul><li>Service </li></ul><ul><ul><li>アプリケーションロジック ( ワークフローロジック)を書く </li></ul></ul><ul><ul><ul><li>複数のモデルにまたがるロジック </li></ul></ul></ul><ul><ul><ul><li>複数のモデルへ処理をディスパッチする 薄い ロジック </li></ul></ul></ul><ul><ul><li>サービスは基本的に 1 ユースケースに対応させる </li></ul></ul><ul><li>Domain Model </li></ul><ul><ul><li>ドメインロジックを記述する </li></ul></ul><ul><ul><li>DB のみの場合 </li></ul></ul><ul><ul><ul><li>一つのテーブル (Schema::X) に依存したビジネスロジック </li></ul></ul></ul><ul><ul><ul><li>Domain Model= ER モデル とする </li></ul></ul></ul><ul><li>Controller は、 Service or Model にアクセス </li></ul><ul><ul><li>Controller にはロジックは記述しない </li></ul></ul><ul><ul><li>ユースケースが CRUD のみのオペレーションに対応する場合、 Domain Model のロジックに直接アクセスしてもよい </li></ul></ul>
  22. 22. Catalyst にマッピングすると POPO Service POPO Models (With DBIC) Catalyst Controller Catalyst View POPO Models (With DBIC) M これが一番シンプルなマッピング モデルに対する要求は他にもあり、他のマッピング方法もある
  23. 23. モデル( Service+Domain Model) を構築するための色々な要求 <ul><li>POPO モデル毎に簡単な設定情報を渡したい </li></ul><ul><li>POPO モデルを簡単に WAF から参照したい </li></ul><ul><ul><li>$c->model() でのアクセスはなんだかんだで便利(インスタンス生成のロジックが隠蔽されてるから) </li></ul></ul><ul><ul><li>モデルと WAF を簡単に繋ぎたい </li></ul></ul><ul><li>POPO モデル間の密な依存関係を断ち切りたい </li></ul><ul><ul><li>Testability 向上のため </li></ul></ul>DI コンテナ を使ってモデルを切り離す
  24. 24. DI コンテナ + POPO Model のアーキテクチャ POPO Service POPO Model (Schema::* など参照 ) Catalyst Controller Catalyst View DIコンテナ Catalyst Plugin DI コンテナで POPO を Wiring Plugin or Controller で DI コンテナを参照し、 WAF と M を繋ぐ
  25. 25. DI コンテナを利用したモデル構築 <ul><li>DI コンテナ利用の利点 </li></ul><ul><ul><li>モデルは DI コンテナで Wiring されるため、モデルが Catalyst の context に依存することが無くなる </li></ul></ul><ul><ul><li>モデル間の実装の依存関係が切れる </li></ul></ul><ul><li>モデル (Service, Model) の参照方法の一例 </li></ul><ul><ul><li>Controller から直に DI コンテナを参照する </li></ul></ul><ul><ul><ul><li>$self->model(“Service::Blog”)->create(); </li></ul></ul></ul><ul><ul><li>プラグイン化して Context から DI コンテナを参照する </li></ul></ul><ul><ul><ul><li>$c->pmodel(“Service::Blog”)->hello(); </li></ul></ul></ul><ul><li>Catalyst::Model::Adaptor じゃできない? </li></ul><ul><ul><li>Catalyst::Model::Adaptor では、 POPO Model と Adaptor が 1:1 対応してしまう </li></ul></ul>
  26. 26. まとめ <ul><li>Catalyst は WAF としては必要十分 </li></ul><ul><li>モデル (Service, Domain Model) について </li></ul><ul><ul><li>モデルは WAF から切り離すべき </li></ul></ul><ul><ul><li>ビジネスロジックはモデルに押し込む </li></ul></ul><ul><ul><li>MVC を考えるときは、モデルの Testability を中心に考える </li></ul></ul><ul><li>モデルのアーキテクチャについて </li></ul><ul><ul><li>Web アプリケーションの多くは、 ServiceLayer + Domain Model の変形でよいのでは </li></ul></ul><ul><li>Catalyst に不足しているもの </li></ul><ul><ul><li>WAF と POPO Model を繋ぐ仕組み </li></ul></ul><ul><ul><ul><li>DI コンテナはそれに対する一つの答え </li></ul></ul></ul><ul><li>MVC の M の拡張などは WAF ではなく、 AF で </li></ul>
  27. 27. ご清聴ありがとうございました !
  28. 28. 付録
  29. 29. Service Layer+Domain Model の構築に必要な仕組み (Application Framework としての仕組み) <ul><li>モデルを Wiring ・設定情報を Inject する仕組み </li></ul><ul><ul><li>DI コンテナ (Bread::Board. あと一歩 ) </li></ul></ul><ul><li>モデルの横断的な関心ごとを切り離す仕組み </li></ul><ul><ul><li>Caching, Transaction など </li></ul></ul><ul><ul><li>Moose or Class::Trigger or Attribute で拡張 </li></ul></ul><ul><li>モデルをプラガブルに拡張する仕組み </li></ul><ul><ul><li>Class::Component </li></ul></ul>
  30. 30. モデルを Catalyst から 切り離すのに実装が必要なもの <ul><li>ConfigLoader </li></ul><ul><li>Logger </li></ul><ul><li>Caching </li></ul><ul><li>Exception </li></ul><ul><li>I18N の仕組み </li></ul>
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×