優れたOOPの本では、多くの場合、継承は持ち越すことができないと書かれており、委任を優先するか、それを連携させる必要があります。 残念ながら、実際にドライ理論を適用する方法をすぐに推測することは常に可能とは限らないので(そして、最終的に「何がそんなに難しいのか」と疑問に思う人もいます)。
そして最初に問題領域について:
31コントローラーアクション。それらのほとんどには、indexAction()、addAction()、editAction()、searchAction()メソッドがあります。
問題番号1:ほとんどではありますが、すべてではありません。 残りの部分では、これらの方法の可用性は異なりますが、
問題#2:editAction()およびaddAction()メソッド自体は非常に大きく、すべてのコントローラーでほぼ同じです;フォームの初期化とモデルの保存が異なります。
決めたとおり、すぐにコードに表示します。
コントローラーの基本クラスのフラグメント
Class Common_Controller extends Zend_Controller_Action { /** * . * @var string; */ protected $modelClass = ''; /** * . * @var string; */ protected $editFormClass = ''; /** * JS , , . * @var string; */ protected $jsModelFile = ''; /** * , * $id - , - . * * @param mixed $id; * @return Model_Record $model; */ protected function modelFactory( $id = null ) { $modelClass = $this->modelClass; if ( $id ) { $model = $modelClass::find( $id ); } else { $model = $modelClass::create(); } return $model; } /** * . * * @param Model_Record $model; * @return Zend_form $form; */ protected function formFactory( Model_Record $model ) { $formClass = $this->editFormClass; $form = new $formClass(); $form->setDefaults( $model->toArray(1) ); return $form; } /** * . * * @param Model_record $model; * @param Zend_Form $form; */ protected function save( Model_Record $model , Zend_Form $form ) { $model->fromArray($form->getValues(), false); $model->save(); } /** * , * editAction() . */ protected function _editActionHelper() { $id = $this->_request->getParam('id'); if ( !$id ) { throw new Zend_Controller_Action_Exception(' ' , 404); } // $model = $this->modelFactory($id); if ( !$model ) { throw new Zend_Controller_Action_Exception(' ' , 404); } $this->view->model = $model; // $this->view->PageTitle = $model->getFullTitle(); // $form = $this->formFactory( $model ); $this->view->form = $form; // get- - ( ) , if ( $this->_request->isGet() ) { $form->redirect->setValue( $_SERVER['HTTP_REFERER'] ); } // , // ... // $model->lock(); // js if ( $this->jsModelFile ) { $this->view->headScript()->appendFile( '/js/models/' . $this->jsModelFile ); } // if ( isset($_POST['save']) || isset($_POST['saveExit']) ) { // if ( $form->isValid( $this->_request->getPost() ) ) { // try { Model::connection()->beginTransaction(); $this->save( $model, $form ); Model::connection()->commit(); $model->releaseLock(); $this->view->Flash()->addSuccess( 'Success !' ); // , // $redirect = '/' . $this->_request->getControllerName() . '/edit/id/' . $model->ID . '?redirect=' . $this->_request->getParam('redirect', '/'); // if ( isset($_POST['saveExit']) ) { $redirect = $this->_request->getParam('redirect', '/'); } $this->_redirect( $redirect ); } catch (Exception $e) { Model::connection()->rollback(); $this->view->Flash()->addError( $e->getMessage() ); } } else { $this->view->Flash()->addError(" "); } } } }
プロテクトメソッドmodelFactory()は、特定のコントローラーに関連付けられたモデルのインスタンスを作成します。 モデルのクラスは変数$ this-> modelClassで指定され、ほとんどの場合、カスタマイズはここで終了します。 モデルを特別な方法で初期化する必要がある場合は、特定のコントローラーでこのメソッドを再定義するだけです。
プロテクトメソッドformFactory()は編集フォームを作成します。カスタマイズはmodelFactory()に似ています。
protected()save()メソッドは、送信されたフォームから渡されたモデルにデータを保存します;特定のコントローラーでエンティティを保存しているエンティティが分散している場合、ここで操作する余地もあります。 コントローラーにそのようなメソッドが存在するかどうかは疑わしいので、save()はモデルの追加メソッドへの呼び出しのみを許可し、SQLクエリはないことを説明します。このため、addTag()、setChannles()などのメソッドを定義します。 1つの不透明なsaveFromArray()メソッドの代わりに。
この構成では、モデルとフォームはお互いについて何も知らず、コントローラーがインテグレーターの役割を果たします。
このフラグメントの最後の保護されたメソッドは_editActionHelper()です。派生クラスでエンティティの編集のサポートが必要な場合は、メソッドを追加します:
public function editAction() { $this->_editActionHelper(); }
他の一般的な方法についても同様です。 例の派生コントローラーのフラグメント:
Class Video extends Common_Controller { protected $modelClass = 'Video'; protected $editFormClass = 'Form_Video'; protected function save( Model_Record $model , Zend_Form $form ) { parent::save( $model , $form ); $model->setChannels( $form->channels->getValue() ); } public function editAction() { $this->_editActionHelper(); } public function addAction() { $this->_addActionHelper(); } public function indexAction() { $this->_indexActionHelper(); } }
PS何か問題があれば、コメントを書いてください。すべての読者に役立つでしょう。