言葉からの連想で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 件のコメント:
コメントを投稿