MVC ならぬ DC モデルによる開発

みたいな場合に、結構使えるかもしれないのが DC モデル(自称)。
最近これにはまっていて、自分が作るものは大抵 DC モデルになってます。
いいモデルか悪いモデルかはさておき、シンプルで分かりやすい作りなので、
ちょと備忘録がてら記事として書きとめておきます。

DC モデルとはなんぞや

Data - Controller モデルです。View?何それおいしいの?
あえて Data を Model としないのは、Model として扱っていないからです。
DC モデルでは、純粋に "ただの" データとして扱っています。

DC モデルのルール

DC モデルのルールはとても単純です。
データを扱うときは、Controller を必ず通して行う。
Controller は、データのやりとり代行以外のことをやらない。
ただこれだけです。
基本的に、データの取得ではハッシュ変数の配列を返し、データの追加・更新では真偽値を返すようにします。

DC モデルの例

実際に例を挙げて見て行きましょう。
簡単なスケジュール管理のWebサービスPHPで作るとします。

扱うデータを決める

扱うデータは、次のものとしましょう。
スケジュールデータの識別IDは、ユーザアカウント情報の通し番号でいいでしょう。

  • ユーザアカウント情報(通し番号、ログインID、パスワード)
  • スケジュールデータ(通し番号、誰のスケジュールか識別するID、題名、場所、内容、開始日時、終了日時)
コントローラの作成

次は、コントローラを作成します。
関数名や引数名から、動作内容についてある程度の予想がつくようにしておくと、分かりやすいです。
ログインチェックなどは、データのIOには関係ないので、コントローラには実装しません。
ScheduleController では、基本的にユーザ単位でのデータ操作となるため、
あらかじめコンストラクタでユーザIDを受け取り、メンバ変数で保持しておきます。

<?php
// Controller/UserAccountController.php
// 通し番号 : user_id (int)
// ログインID : login_id (string)
// パスワード : password (string)
class UserAccountController {
  function CreateUserAccount( /*string*/ $login_id, /*string*/ $password ) { ... }
  function GetUserAccount( /*string*/ $login_id ) { ... }
  function RemoveUserAccount( /*string*/ $login_id ) { ... }
  function UpdateUserAccount( /*string*/ $user_id, /*string*/ $new_login_id, /*string*/ $new_password ) { ... }

}
$ua_con = new UserAccountController();
<?php
// Controller/ScheduleController.php
// 通し番号 : schedule_id (int)
// 誰のスケジュールか識別するID : user_id (int)
// 題名 : title (string)
// 場所 : location (string)
// 内容 : detail (string)
// 開始日時 : start (date)
// 終了日時 : end (date)
class ScheduleController {
  private $user_id; // 誰のスケジュールデータか
  function ScheduleController( /*int*/ $user_id ) { $this->user_id = $user_id; }

  function AddSchedule( /*string*/ $title, /*string*/ $location, /*string*/ $detail, /*date*/ $start = date('Y/m/d H:i:s'), /*date*/ $end = null ) { ... }
  function GetSchedule( ) { ... }
  function GetScheduleByDate( /*int*/ $year, /*int*/ $month = null, /*int*/ $day = null ) { ... }
  function RemoveSchedule( /*int*/ $schedule_id ) { ... }
  function UpdateSchedule( /*int*/ $schedule_id, /*string*/ $new_title, /*string*/ $new_location, /*string*/ $new_detail, /*date*/ $new_start = date('Y/m/d H:i:s'), /*date*/ $new_end = null ) { ... }

}


コントローラを作ったら、適当なスクリプトで個別の関数の動作テストを行っておきます。
適当に require_once して、次のようなコードを実行させて、
データファイルやデータベースが正常に更新されてればOKです。

<?php
// test.php
$ua_con->CreateUserAccount( "hoge", "mofu" ); とか、
$account = $ua_con->GetUserAccount( 3 ); とか、
$account_scon = new ScheduleController( $account[ 'user_id' ] );
$account_scon->GetScheduleByDate( 2012, 7 );
その他の部分を実装

データのIO部分は完成したので、後はデータの処理と表示部分だけです。
ときどき、コントローラに欲しい操作を追記することもあるでしょう。
こうして、データの入出力に考えをとられることなく、
ユーザが見ることになる画面(ビュー)と、データの処理に注力できるようになります。


複数人開発のときには、コントローラの仕様をあらかじめ決定しておき、
コントローラの開発と、それ以外の部分の開発として分担することもできます。
特にコントローラの実装は、かなり単純な内容なので、
プログラミング初心者でも(テンプレートがあれば)作れなくもないレベルだと思います。

DC モデルのメリットとデメリット

メリットは、

  • 単純で分かりやすい
  • データのIOと処理や表示の実装を分離できる

という点でしょうか。コントローラの中の処理も、テキストやSQLXMLなどに切り替えられますね。

対して、デメリット。

  • 扱うデータのオブジェクトとしての可視性が低い

データをオブジェクト単位で扱っていない(ただのハッシュの配列としてしか扱っていない)ので、
どうしてもしょうがないところなのかもしれません。