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