Separate Model from Catalyst

  • 9,174 views
Uploaded on

catalystcon1

catalystcon1

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
9,174
On Slideshare
0
From Embeds
0
Number of Embeds
2

Actions

Shares
Downloads
20
Comments
0
Likes
7

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

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