我和我的同事正在争论我们是否应该在我们的项目中重用某些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'
)
));
我的同事认为这是正确的方法,因为还有一些表格不会出现联系人的每个字段,重新使用该字段集会通过加载更多信息来提供额外的开销。 / p>
我反过来认为有两个类(几乎)相同的代码总是不好的做法,因此我们应该重用同一个类,并且只有在实际存在差异时才创建一个新类。这样我们在不同的地方就没有相同的代码,如果发生变化,这应该减少我们应该改变代码的地方数量。
或者,我建议应该有一个带有最小FieldSet的基类,名为BaseContactFieldSet,它包含所有表单将始终使用的所有字段,并且其他FieldSet类应该扩展到该类并添加任何输入元素。不在BaseContactFieldSet中。
我的同事认为每个表单都有太多的例外,因此有必要在不同的地方创建大量重复的代码,并且我们不应该重复使用FieldSet类来阻止创建代码处理异常。
所以我们想知道其他人的想法。我们应该尽可能多地重复使用代码,还是应该创建重复代码,因为特定表单可能有例外?
答案 0 :(得分:1)
最佳做法是干眼方法(不要重复自己)而不是WET方法(写一切两次)。
将公共元素添加到AccountFieldset(在此考虑一个抽象类),然后使用EmployeeAccountFieldset和CustomerAccountFieldset扩展它。
使用FormElementManager服务注册具体的字段集类,然后您可以从有权访问serviceManager的任何地方访问字段集对象,它们将被延迟加载,因此如果您不调用该服务,它们将永远不会被实例化。
在您的模块配置中:
var data = [];
data.push(1);
data.push('foo');
data.push(['hello', 'world']);
// data is now: [ 1, 'foo', ['hello', 'world'] ]
如果您需要为特定用途添加/删除某些元素,您还可以调整fieldsetObjects(而不是类本身)。
return [
'form_elements' => [
'invokables'=>[
'MyNameSpace\Form\Fieldset\EmployeeAccount'=>'MyNameSpace\Form\Fieldset\EmployeeAccountFieldset'
]]];