双向数据填充设计模式

时间:2019-02-01 22:04:18

标签: php inheritance design-patterns covariance specialization

我希望以更正式,更通用的方式实现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。策略模式和桥接模式都看似可行,但我不清楚两者如何解决协方差问题。

0 个答案:

没有答案