Наилучшая практика для Zend 2 FieldSets, использовать их повторно или создавать заново для каждой конкретной ситуации?

1

Я и мой коллега спорили о том, следует ли нам повторно использовать некоторые классы Zend2 FieldSet в нашем проекте. Используя фреймворк, мы создаем много разных форм, и существует довольно много форм, для которых необходимо заполнить одну и ту же информацию. Например, у нас есть форма для создания нового сотрудника и формы для создания нового контактного лица. Для обеих форм контактная информация должна быть заполнена, поэтому обе формы добавляют к форме форму AccountFieldSet.

Теперь в настоящее время для каждой новой формы создается новый AccountFieldSet, поэтому у нас есть Customer\Form\Contact\AccountFieldset и Employee\Form\AccountFieldSet, которые содержат код типа:

<?php
namespace Employee\Form;

use Zend\InputFilter\InputFilterProviderInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Zend\Form\Fieldset;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject;
use OurProject\Entity\Account;

class AccountFieldset extends Fieldset implements InputFilterProviderInterface
{

    public function __construct(ObjectManager $oObjectManager)
    {
        parent::__construct('account');

        $this->setHydrator(new DoctrineObject($oObjectManager))->setObject(new Account());

        $oAccountAddressFieldset = new AccountAddressFieldset($oObjectManager);
        $this->add($oAccountAddressFieldset);

        $this->add(array(
            'type' => 'DoctrineModule\Form\Element\ObjectSelect',
            'name' => 'listGender',
            'options' => array(
                'empty_option' => '',
                'object_manager' => $oObjectManager,
                'target_class' => 'OurProject\Entity\ListGender',
                'property' => 'name'
            ),
            'attributes' => array(
                'class' => 'select2',
                'data-placeholder' => 'Gender'
            )
        ));

        $this->add(array(
            'type' => 'Zend\Form\Element\Text',
            'name' => 'firstname',
            'attributes' => array(
                'class' => 'form-control input-xs',
                'placeholder' => 'First name',
                'required' => 'required'
            )
        ));

Мой коллега утверждает, что это правильный путь, потому что есть также формы, для которых должно появляться не каждое поле Контакт, и повторное использование этого FieldSet затем дает дополнительные накладные расходы, загружая больше необходимой информации.

Я в свою очередь считаю, что у двух классов (почти) один и тот же код всегда является плохой практикой, и поэтому мы должны повторно использовать один и тот же класс и создавать только новый, когда есть различия. Таким образом, у нас нет одинакового кода в разных местах, что должно уменьшить количество мест, где мы должны изменить код, если изменения произойдут.

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

Мой коллега полагает, что существует слишком много исключений для каждой формы, и поэтому необходимо просто создать много дубликатов кода в разных местах и что мы не должны повторно использовать классы FieldSet вообще, чтобы предотвратить создание кода для обработки исключений.

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

Теги:
forms
doctrine2
zend-framework2

1 ответ

1
Лучший ответ

Лучшая практика - это СУХОЙ подход (не повторять себя), а не подход WET ("Пишите все дважды").

Добавьте общие элементы в AccountFieldset (рассмотрите здесь абстрактный класс), а затем расширьте его с помощью EmployeeAccountFieldset и CustomerAccountFieldset.

Зарегистрируйте конкретные классы fieldset с помощью службы FormElementManager, и вы можете получить доступ к объектам fieldset из любого места, где у вас есть доступ к serviceManager, они будут ленивы, поэтому, если вы не позвоните в службу, они никогда не получат экземпляр.

в конфигурации вашего модуля:

return [  
        'form_elements' => [
                'invokables'=>[
    'MyNameSpace\Form\Fieldset\EmployeeAccount'=>'MyNameSpace\Form\Fieldset\EmployeeAccountFieldset'
]]];

Затем вы можете настроить параметры fieldsetObjects (а не сам класс), если вам нужно добавить/удалить определенные элементы для определенных способов использования.

        //get fieldset object via the FormElementManager ServiceManager
        $employeeAccountFieldset=$this->getServiceLocator()->get('FormElementManager')->get('MyNameSpace\Form\Fieldset\EmployeeAccount');

        //remove password element
        $employeeAccountFieldset->remove('password');

        //tweak an element
        $employeeAccountFieldset->get('email')->setAttribute('class','myCSSClass');

        //add tweaked fieldset to form
        $myFormObject->add($employeeAccountFieldset);
  • 0
    Спасибо за ваш ответ. Я согласен с подходом СУХОЙ против ВЛАЖНОЙ. Мой коллега, к сожалению, все еще не убежден, но я думаю, что для этого требуется гораздо больше ответов, чего я не вижу в ближайшее время.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню