СУХОЙ: Советы, как не дублировать код? - PullRequest
1 голос
/ 22 ноября 2010

Хорошо, вот и мой вопрос, у меня есть база данных с такой схемой

+-------------+ +------------+ +-----------+ 
+ 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 Framework и на PHP.

Я хотел бы сделать что-то более "Не повторяйся" и не нужно дублировать весь код.Есть идеи, как сделать это более элегантно?

Ответы [ 3 ]

2 голосов
/ 22 ноября 2010

Я поделюсь с вами своим базовым классом 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';
}

Надеюсь, это поможет;)

1 голос
/ 22 ноября 2010

Я сделал что-то похожее на Томаша Фейфара ...

Создание базового контроллера CRUD и класса базовой модели, в котором есть методы CRUD.Вы даже можете использовать универсальные сценарии представления, которые будут работать для всех типов контента для базовых шаблонов CRUD.

В каждом контроллере все, что вам нужно, это несколько переменных вверху, чтобы внести любые необходимые изменения.

1 голос
/ 22 ноября 2010

Вам нужно будет создать мета-таблицу с информацией о каждом типе объекта, то есть о том, какие поля у него есть, как отобразить каждое из них (например, ввести или выбрать), их порядок и тому подобное.

Затем вы можете получить доступ к главному контроллеру, только передав ему имя объекта, и тогда он должен сгенерировать соответствующие формы CRUD.

...