2012年12月2日日曜日

ウェブでのInteractionとContextの実装例

前回前々回に書きなぐったDCIの続きです。
あのあと試行錯誤しながらコードを書いているうちに、自分なりに納得できるところまで来ました。ということで、もう1ヶ月以上コーディングしてるんですね。なお、今回は実際に動かしました。

参考コード: https://gist.github.com/4185350
実際に動かすには、他のオブジェクトが必要です。

interactで登録フォーム



インターアクションを使った登録フォームのコードです
動きも今までと同じ、ただしメソードも含めて
  1. get form : フォームを表示。
  2. post form : フォームからの登録を読み込む。
  3. get confirm : トークンをつけて確認画面を表示。
  4. post save : トークンを確認したらデータを保存して、完了画面を表示。
という処理を行います。

ここにあるContextというのは、処理のまとまり、なわけですが…

コンテキストってなんでしょう?
日本語だと文脈なのですが。

このコードでは、
  • データ(エンティティ)に操作して何らかの処理を行う、
  • アクションがコンテキストに対応しているかどうかを判断する、
というルーチンをコンテキストと呼んでます。

今の実装だと、contextXXXからの返り値がfalse以外の場合はコンテキストに対応するので、ビューを表示します。

一方、返り値がfalseの場合は(なんか処理は行ったかもしれないけれど)コンテキスト外なので次の処理に進みます。

contextFormAndLoad


例として、contextFormAndLoadの処理を簡単に説明すると、
  • 必ず一回はフォームを表示する(trueを返す)。
  • アクションが$formと一致する(trueを返す)。
  • アクションが$formと一致しメソードがポストの場合は$_POSTからデータを読み込んでエンティティに書き込む(コンテキストと関係なく必ず処理されます)。
  • 必ずデータはバリデートする。
  • バリデーションで問題があった場合(trueを返す)。
返り値がtrueの場合、コンテキストに対応するということで登録フォームを表示します。複雑ですね。

そのコードです
複雑怪奇ですね。

最初に納得したとか書きましたが…
自分でしか理解できないコードな気がします。

また、このブログを書きながら、コードを見なおしてみて、切り分け方が今ひとつだなと感じてるし… また後で、書きなおす予定。

Interactionクラス


さて、今回のコードの基本がInteractionクラス。セッションに自分自身の状態を保持・読み出します。エンティティも最初に一度作り、あとはセッションから読みだします。

フォームを一度だけ表示する、データを二重に保存しない、という機能を実現するためにpinPoint/checkPinという簡単なメソードを使うことで実現しました。$this->checkPin( 'save' );とすれば、一度だけsaveの状態を実行できます。

なお、ピンだけだとCSRF対策としては弱いと思うので、
別にトークンを使ってます。

ココらへんをInteractionクラス側に隠したことで、処理フローを制御しているのが$actionのみ(に見える)ため、前回よりコードが(少しは)見通しが良くなったと思ってます。

大事なのは、汎用性が高く、使いやすくて、バグのない、コンテキストをたくさん用意できるか?という事になりそうです。

0 件のコメント: