powered by nequal

rhaco1-doc :: 100-blog-tutorial/08-mtv-pattern.txt

http://wikihub.org/wiki/rhaco1-doc/100-blog-tutorial/08-mtv-pattern

Table of contents:

collapse all expand all

Updates:

MTV を知ろう

※注意 @yabeken の独断と偏見が入ってます.一開発手法に過ぎないので参考程度にどうぞ.

MTV とは?

MTV は Django で使われ始めた用語(*1)のようです.

ごくごく簡単に言うと,MVC とは次のような対応になります.

  • Model -> Model
  • View -> Template
  • Controller -> View

イメージはこんな感じ.ただし,MVC とはそれぞれの持つ役割が大きく異なります.

Model

Model は,大概の場合テーブルを指しますよね.フックメソッドで処理を追加したり,cakephp でしたら ビヘイビア を追加しますね.

rhaco では,ビヘイビアは無いですが,project.xml を記述することで,テーブルモデル + alpha だけではなく次のような様々な付加機能が利用可能です.

  1. DbUtil と連携したフックメソッド
  2. 汎用 Views と連携したフックメソッド
  3. 検証処理の拡張
  4. 格納値の出力書式の変更
  5. 格納値の出力(HTML)表現の変更
  6. project.xml で定義した付加情報・制限の保持・処理
    • データ型による入力値の簡易制御
    • 最大値,最小値,必須,一意,正規表現制御等
    • デフォルト値の設定
    • 入力値の選択制限
    • 仮想列の定義
    • (setup の機能ですが)モデルの継承

前節の最後で触れた仮想列とモデルの継承を合わせることで,アプリケーション構築に対して非常に明確な指針を提供します.

View

View は,MVC でいう Controller に当たりますが,汎用 Views として次の View があらかじめ準備されていますので,所謂 Controller とは,役割が大きく異なります.

  1. create
  2. confirmedCreate
  3. update
  4. confirmedUpdate
  5. detail
  6. drop
  7. read

これらの 汎用 View が用意されているため,構築するアプリケーションの View は大きく二つの処理に分けることができます.

  1. 汎用 View にモデルを渡すまでの事前処理
    • View の実行可否の判断
    • 利用するモデルの選択
    • テンプレートに渡すデータの準備,受け渡し
  2. 汎用 View にモデルやパラメータを渡す

実際の構築の場面では,上記の汎用 View で構築するアプリケーション全体の八割近くをカバーすることができます.

Template

Template は,View から渡されたモデル等のデータを用いて,それらをどのように見せるかを決定します.

ここで注意しなければならないのは,「Template は表示制御行うが,ロジックは記述しない」ということです.

ロジックは記述が記述されている例としては,次のような例が挙げられます.

  • <rt:if /> がネストしている
  • <?php ?>を使っている

rhaco の TemplateParser は拡張性を排除しているので,ロジックが入り込む余地はあまりないですが,上記のコードが見られる場合には,View での前処理が不十分ということです.

モデルの階層化

project.xml で,"<ext />" タグを用いることによって,テーブルモデルを継承した拡張テーブルモデルを作成することができます.

  • Profile
    • UserProfile
    • AdminProfile

ここから,各処理毎のクラスを作成します.

  • library/form/user/UserProfileUpdate.php
  • library/form/admin/AdminProfileUpdate.php
<?php
Rhaco::import("model.UserProfile");
/**
 * ユーザによるプロフィール更新
 */
class UserProfileUpdate extends UserProfile{
}

上記のように,ある特定の処理ごとに階層化しモデルを作成することによって,

  • 汎用 View の機能であるテンプレートの差し替えが全ての処理ごとに可能
  • 階層化することによって,共通処理の落とし込みが可能
  • 処理ごとにモデル分けを行うことにより,特定の処理専用の機能追加,変更が非常に楽
  • 仮想列を用いることにより,データテーブルの ID に依存した URL の生成などをモデルに落とし込める.

簡単な例を挙げると,次のような例があります.

  • メールアドレス入力確認仮想列と検証メソッドを必要な処理モデルのみに記述する
  • メールの送信を処理モデルの afterUpdate 等に記述することで,View はあくまでも,モデルをどう扱うかに特化させる
  • あるテーブルレコードの更新ボタン仮想列を権限モデルに記述し,HTML出力表現を記述することで,テンプレートから URL 生成ロジックを排除する.(やり過ぎな気もしないでもないですが)

ただし,上記の例はごく小さなアプリケーション(権限をデータベースで管理していない)場合なので,該当しない場合も多々あります.

参考