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

发布于 2024-10-03 17:01:27 字数 825 浏览 4 评论 0原文

好的,我的问题来了,我有一个具有这种方案的数据库

+-------------+ +------------+ +-----------+ 
+ 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

因此,对于每种类型,我基本上复制所有代码并更改几行代码(即用计算机映射器替换汽车映射器,对于记录对象也是如此)。我不得不提一下 zend 框架的应用程序,它是用 PHP 编写的。

我想做更多“不要重复自己”的事情,而不必重复所有代码。知道如何更优雅吗?

Ok here come my question, I have a database with such scheme

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

So to summarize when my user input a computer for example, I create a object record, save all shared fields into it and I create a computer record with all specific data for computers being saved.

So far so good, here comes my problem by doing so I would have to duplicate every action (and controller methods view for each type of objects). So right now in my Controller, I have those actions:

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

So for each type I basically duplicate all the code and change few lines of codes (i.e replacing the car mapper by computer mapper, same for record object). I have to mention the application you the zend framework and is in PHP.

I would like to do something more "Don't repeat yourself" and not having to duplicate all the code. Any idea how to it more elegantly?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

ま昔日黯然 2024-10-10 17:01:27

我将与您分享我的基本 CRUD 课程。按原样提供。自己测试一下。可能会出现一些错误;)

<?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';
}

希望这会有所帮助;)

I'll share with you my basic CRUD class. Supplied as-is. Test for yourself. Some bugs may be ;)

<?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){}

}

And then a concrete implementation:

<?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';
}

Hope this helps ;)

一片旧的回忆 2024-10-10 17:01:27

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

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

You'll have to create a meta-table with information on each type of object, i.e. what fields it has, how to display each of them (input or select for example), their order and stuff like that.

Then you can access the main controller, only passing the object name to it and it it then should generate the appropriate CRUD forms.

开始看清了 2024-10-10 17:01:27

我做了类似于 Tomáš Fejfar 的事情...

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

在每个控制器中,您只需要顶部的一些变量即可进行必要的更改。

I did something similar to Tomáš Fejfar...

Create a base CRUD controller, and a base model class which has CRUD methods. You can even use generic view scripts that will work for all content types for basic CRUD templates.

In each controller, all you'd need is a few variables at the top to make any alterations necessary.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文