代码之家  ›  专栏  ›  技术社区  ›  RageZ

干:建议如何不重复代码?

  •  1
  • RageZ  · 技术社区  · 14 年前

    好的,我的问题来了,我有一个数据库有这样的计划

    +-------------+ +------------+ +-----------+ 
    + Object      + + car        + + computer  +
    +-------------+ +------------+ +-----------+
    + id          + + object_id  + + object_id +
    + some_col    + + max_speed  + + CPU_speed +
    + type        + + n_gears    + + memory    +
    +-------------+ +------------+ +-----------+
    

    例如,当我的用户输入一台计算机时,我创建一个对象记录,将所有共享字段保存到其中,并创建一个计算机记录,其中包含所有正在保存的计算机的特定数据。

    到目前为止,我的问题是这样做,我必须复制每一个操作(以及每种类型对象的控制器方法视图)。所以现在在我的控制器里,我有这些动作:

      + new-car
      + new-computer
      + show-car
      + show-computer
      + edit-car
      + edit-computer
      + list-car
      + list-computer
    

    因此,对于每种类型,我基本上复制所有的代码,并更改几行代码(即用计算机映射器替换汽车映射器,对record对象相同)。我不得不提到应用程序你的zend框架和在PHP中。

    我想做更多的事情“不要重复你自己”,不必重复所有的代码。你知道怎样才能更优雅吗?

    3 回复  |  直到 14 年前
        1
  •  2
  •   TomáÅ¡ Fejfar    14 年前

    我将和你分享我的基本积垢课程。按原样供应。为你自己测试。一些错误可能是;)

    <?php
    abstract class Controller_Crud extends Controller 
    {
    /* definované v dalších třídách */
    protected $_viewKey = '';
    protected $_url = 'admin/';
    protected $_modelClass;
    protected $_formClass;
    protected $_filterFormClass = null;
    protected $_title = 'Untitled';
    
    /* pro vnitřní potřebu */
    protected $_model;
    protected $_form;
    protected $_filterForm;
    private $_defaultViewKey = 'crud';
    
    /* 
     * Inicializace třídy, vytvoření instancí modelů a formulářů
     * @see Tul/Controller/Tul_Controller_Admin#init()
     */
    public function init()
    {
        parent::init();
        $this->_model = new $this->_modelClass();
        $this->_form = new $this->_formClass();
        $this->view->indexUrl = $this->_url;
        $this->view->viewKey = $this->_viewKey;
        $this->view->title = $this->_title;
    }
    
    public function postDispatch()
    {
        // Po provedení akce je nastaven titlek
        $this->view->headTitle($this->_title);
    }
    /**
     * základní akce zabezpečující výpis záznamů a filtrování
     * @return void
     */
    public function indexAction ()
    {
        if(null !== $this->_filterFormClass){
            $this->_filterForm = new $this->_filterFormClass;
        }
        $filter = null;
        if(null !== $this->_filterFormClass){
            if($this->_getParam('filter') && $this->_filterForm->isValid($this->_getAllParams())){
                $filter = $this->_filterForm->getValues();
            }
            $this->_filterForm->populate($this->_getAllParams());
    
        }
        /* @var Tul_Paginator */
        $paginator = $this->_model->getAllPaginator($filter);
        $paginator->setCurrentPageNumber($this->_getParam('page',1));
        $this->view->data = $paginator;
        $this->view->form = $this->_filterForm;
    }
    
    /* 
     * Načte ID záznamu a pokud není nalezeno přesměruje s chybovou hláškou na hlavní stránku
     * @see Tul/Controller/Tul_Controller_Admin#getId()
     */
    public function getId()
    {
        $id = $this->_getParam('id', false);
        if(false === $id){
            $this->addFlashMessage('error','Neplatné ID.');
            $this->_gotoUrl($this->_url);
        }
        return $id;
    }
    
    /**
     * akce pro přidání nového záznamu
     * @return void
     */
    public function pridatAction ()
    {
        $this->view->headTitle('Přidat');
        if ($this->_request->isPost()) {
            if ($this->_form->isValid($_POST)) {
                $data = $this->_form->getValues();
                try {
                    $this->_beforeAdd($data);
                    $result = $this->_model->insert($data);
                    $this->_afterAdd($data, $result);
                    $this->addFlashMessage('success','Úspěšně přidáno. ');
                } catch (Exception $e){
                    $this->addFlashMessage('error','Došlo k chybě při přidávání:<br />' . htmlspecialchars($e->getMessage()));
                }
                $this->_gotoUrl($this->_url);
            } else {
                $this->_form->populate($_POST);
            }
        }
        $this->view->form = $this->_form;
        $this->_renderView('pridat.phtml');
    } 
    
    /**
     * Akce pro smazání záznamu
     * @return void
     */
    public function smazatAction ()
    {
        $id = $this->getId();
        try{
            $this->_beforeDelete($id);
            $result = $this->_model->delete($this->_model->quoteInto('id = ?',$id));
            $this->_afterDelete($id, $result);
            $this->addFlashMessage('success','Úspěšně smazáno. ');
        } catch (Exception $e){
            $this->addFlashMessage('error','Došlo k chybě při mazání:<br />'.htmlspecialchars($e->getMessage()));
        }
        $this->_gotoUrl($this->_url);
    } 
    
    /**
     * akce pro úpravu záznamu
     * @return void
     */
    public function upravitAction ()
    {
        $this->view->headTitle('Upravit');
        $id = $this->getId();
        $item = $this->_model->getById($id);
        if ($this->_request->isPost()) {
            if ($this->_form->isValid($_POST)) {
                $data = $this->_form->getValues();
                try {
                    $this->_beforeUpdate($data, $item);
                    $result = $this->_model->update($data, $this->_model->quoteInto('id = ?',$id));
                    $this->_afterUpdate($data, $result);
                    $this->addFlashMessage('success','Úspěšně upraveno. ');
                } catch (Exception $e){
                    $this->addFlashMessage('error','Došlo k chybě při úpravě:<br />'.htmlspecialchars($e->getMessage()));
                }
                $this->_gotoUrl($this->_url);
            } else {
                $this->_form->populate($_POST);
            }
        } else {
            $this->_form->populate((array)$item);
        }
        $this->view->form = $this->_form;
        $this->_renderView('upravit.phtml');
    }
    
    /**
     * Pokud existuje načte pohled zděděné třídy, pokud neexistuje použije interní
     * @param $name string název pohledu
     * @return void
     */
    private function _renderView($name)
    {
        $completeName = $this->_viewKey . '/' . $name;
        /* @var Zend_View_Abstract */
        foreach ($this->view->getScriptPaths() as $dir) {
            if (is_readable($dir . $completeName)) {
                return $this->renderScript($completeName);
            }
        }
        return $this->renderScript($this->_defaultViewKey . '/' . $name);
    }
    
    /**
     * Metoda, která je zavolaná těsně před přidáním záznamu. 
     * Umožňuje upravit data podle potřeby před vložením do databáze. 
     * Vyhozením vyjímky přidání záznamu skončí chybou
     * @param $data array data, která budou přidána
     * @return void
     */
    protected function _beforeAdd(&$data){}
    /**
     * Metoda, která je zavolaná těsně po přidání záznamu. 
     * Umožňuje upravit data podle potřeby ještě po vložení do databáze. 
     * Vyhozením vyjímky přidání záznamu skončí chybou
     * @param $data array data, která budou přidána
     * @param $result mixed primární klíč přidaného záznamu
     * @return void
     */
    protected function _afterAdd(&$data, $result){}
    /**
     * Metoda, která je zavolaná těsně před úpravou záznamu. 
     * Umožňuje upravit data podle potřeby ještě před úpravou v databázi. 
     * Vyhozením vyjímky uprava záznamu skončí chybou
     * @param $data array data, která budou upravena
     * @param $item mixed původní data
     * @return void
     */
    protected function _beforeUpdate(&$data,$item){}
    /**
     * Metoda, která je zavolaná těsně po úpravě záznamu. 
     * Umožňuje upravit data podle potřeby po úpravě v databázi. 
     * Vyhozením vyjímky uprava záznamu skončí chybou
     * @param $data array data, která budou upravena
     * @param $result integer počet ovlivněných záznamů
     * @return void
     */
    protected function _afterUpdate(&$data,$result){}
    /**
     * Metoda, která je zavolána před smazáním záznamu. 
     * Vyhozením vyjímky smazání záznamu skončí chybou
     * @param $id id mazaného záznamu
     * @return void
     */
    protected function _beforeDelete($id){}
    /**
     * Metoda, která je zavolána po smazání záznamu. 
     * Vyhozením vyjímky smazání záznamu skončí chybou
     * @param $id id mazaného záznamu
     * @param $result počet smazaných řádků
     * @return void
     */
    protected function _afterDelete($id, $result){}
    
    }
    

    然后具体实施:

    <?php
    class FunkceController extends Controller_Crud
    {
        protected $_url = '/admin/funkce/';
        protected $_modelClass = 'Admin_Functions';
        protected $_formClass = 'Form_Admin_Functions';
        protected $_filterFormClass = 'Form_Admin_FilterFunctions';
        protected $_viewKey = 'funkce';
        protected $_title = 'Funkce';
    }
    

    希望这有帮助;)

        2
  •  1
  •   raveren    14 年前

    您必须创建一个元表,其中包含关于每种对象类型的信息,即它有哪些字段、如何显示每种字段(例如输入或选择)、它们的顺序以及类似的内容。

    然后您可以访问主控制器,只需将对象名传递给它,然后它就应该生成适当的CRUD表单。

        3
  •  1
  •   Adrian Schneider    14 年前

    我做了一些类似于汤姆·费法尔的事。。。

    创建一个基CRUD控制器和一个包含CRUD方法的基模型类。您甚至可以使用通用视图脚本,该脚本将适用于基本CRUD模板的所有内容类型。

    在每个控制器中,您所需要的只是顶部的一些变量,以便进行任何必要的更改。