言葉からの連想で15行程度の関数を書いた。
そこから、継続とかの難しい言葉を覚えて、更に書き換えていたのだが…
難しい。
ウェブサイトのページをコントロールするので、
ページの順番、入力のバリデーション、DB登録の制御、特にCSRF対策、などをきっちりと行おうと思うと、それなりに複雑になってしまった。
せいぜいif文で2レベルの深さにも関わらず、だ。
で、そのコード。
関数、ではなくて、あるクラス内のメソード。
entityというデータについて、
・form1:フォーム1の表示、load1:入力の読み取り、バリデーション、
・form2:フォーム2の表示、load2:入力の読み取り、バリデーション、
・confirm:確認画面の表示、
・save:そしてDBに登録する処理。
ただし確認画面の表示で、入力内容が気に入らなければ、フォーム1あるいは2を再表示して再入力して、入力に問題がなければ確認画面に戻る、という仕様を実装してみた。
(まだ実行してないので動くかどうかは知らない)
($viewやcontextとは何かとかも気にしない)
/** * @param string $control * @param view $view * @return \view */ function entityAdd( $control, $view ) { // get entity $entity = $this->restore( 'entity' ); $state = $this->getState(); if( !$state ) { $entity = $this->contextGet( 'entity' ); $this->register( 'entity', $entity ); $this->setState( array( 'form1', 'form2', 'confirm', 'save', 'done' ) ); } $role = $this->applyContext( $entity, 'loadable' ); // form1 if( $control == 'form1' || $state == 'form1' ) { $this->nextStateIf( 'form1' ); return $view->showForm1( $entity ); } // load1 if( $control == 'load1' ) $role->load( 'load1' ); if( !$role->verify( 'load1' ) ) return $view->showForm1( $entity );
// form2 if( $control == 'form2' || $state == 'form2' ) { $this->nextStateIf( 'form2' ); return $view->showForm2( $entity ); } // load2 if( $control == 'load2' ) $role->load( 'load2' ); if( !$role->verify( 'load2' ) ) return $view->showForm1( $entity ); if( $control == 'save' && $state == 'confirm' ) $this->nextState(); // confirm if( $state == 'confirm' ) { return $view->showConfirm( $entity ); } // save if( $state == 'save' ) { $role = $this->applyContext( $entity, 'active' ); $role->insert(); $this->nextState(); } // done return $view->showDone( $entity ); }
複雑な理由は、制御変数が2つもあるから。
ひとつは$state、セッションに保持していて「〜〜まで実行」を制御する。
一方は、$control、フォームからの入力値で「〜〜から実行」あるいは「〜〜を実行」を制御する。
ステートが出てくるので、ステートパターンの出番だと思うが、
最初の発想が、処理が複数のクラスの分割されてしまって理解が難しくなる、というOOの問題の提起があって、対処方法として関数で逐次処理するという提案だった。なので、複雑なのでOOでクラスに分割して・・・では解決にならないw
とはいえ、理解しやすいコードとは到底言えない。
0 件のコメント:
コメントを投稿