我希望以更正式,更通用的方式实现this strategy for using Symfony Form data classes。
tl; dr:基本思想是将表单数据捕获到一个平坦的,可容忍的对象中,然后执行验证。如果通过验证,则将表单数据填充到更严格的层次化ORM实体结构中。如果要修改现有数据,请首先从ORM数据初始化表单数据。
以最简化,不受支持的协变形式,看起来像这样:
abstract class FormDataInterface
{
protected $entity;
public function __construct(EntityInterface $entity)
{
$this->entity = $entity;
}
abstract public static function initialize(EntityInterface $entity): self;
abstract public function populate(): void;
}
/**
* Each concrete child is a two-way adaptor responsible for defining its own
* data members and rules for populating initial form data and repopulating the
* data back into the entity. (In practice, this is very unique and sometimes
* complicated)
*/
class UserData extends FormDataInterface
{
private $name;
public function __construct(UserEntity $user)
{
parent::__construct($user);
}
// accessors for private members
public static function initialize(UserEntity $user): self
{
$userData = new self($user);
$userData->setName($user->getName());
return $userData;
}
public function populate(): void
{
$this->entity->setName($this->name);
}
}
问题是EntityInterface专门用于特定的具体实体。系统规则表明,每个具体表单数据类都将与特定实体配对。另外,我希望能够在合同中以某种方式定义initialize()和populate()方法。
我已阅读this issue。策略模式和桥接模式都看似可行,但我不清楚两者如何解决协方差问题。