2

我对验证实体中的值的 OOP 策略有疑问。可以说我有这样的实体:

/*
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="My\PageBundle\Entity\PageRepository")
 */
class File {
    /*
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /*
     * @ORM\Column(name="type", type="string")
     */
    private $type;

    /*
     * @ORM\ManyToOne(targetEntity="File")
     * @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
     */
    private $parent;
}

现在我只想实体类型“父母”可能是父母。我可以通过两种方式做到这一点。

  1. 使用Symfony 回调验证

    if ($this->getParent() != null && $this->getParent()->getType() != 'group') $context->addViolationAt('parent', 'Invalid parent.', array() , 无效的);

这很明显,但仅在我调用验证器时才有效,或者

  1. 把这个逻辑放在 setter 中,就像在Symfony 书中提出的那样

    您应该检查生成的实体并根据自己的需要调整 getter/setter 逻辑

例如:

setParent(File $parent) {
    if ($parent->getType() != 'group')
        throw new \Exception('Invalid parent');
    $this->parent = $parent;
}

哪种方法更好?使用专门为此目的创建的验证约束或 getter 和 setter?如果使用验证 - 我应该始终使用默认的 getter 和 setter,还是我可以在其中做任何花哨(且有用)的事情(任何示例)?

4

1 回答 1

3

我会使用 Symfony 回调验证,首先是因为它是用于验证实体的专用构造,并且因为您的示例更接近用于回调验证的组件的设计理念。

虽然 PHP OOP 书籍确实鼓励您不仅使用 getter 和 setter 来检索属性值,但我一直使用它们来确保字段的默认值和约束(即我有一个$id属性,它的类型为int,并且我想确保在设置时将$id的值转换为int,即使有人错误地发送了字符串/其他内容)。

除此之外,我还认为设置器的 try/catch 块很奇怪,尤其是当我知道我正在发送正确的参数类型时。

更新:刚刚注意到你问题的最后一部分。我使用我的 Symfony getter 和 setter 基本上只是为了检索/存储值。我倾向于为构造函数中的事物设置默认值。多年来,我已经看到一些代码,其中 getter 和 setter 做了一些非常疯狂的事情,这实际上不属于实体的范围,而是更接近于服务或存储库。

我认为 Entities 是允许我将数据库表映射到 PHP 类的结构——它们不需要是smart、特殊或在该范围之外做任何事情。

我更喜欢让它们保持简单并使用架构的其余部分来补充可能的操作。它是否提供了一些通用功能并且可以独立隔离?为此做一个服务。是否与操纵实体、检索某些信息或以特定方式处理它们有关?为此创建一个存储库。

于 2013-10-11T20:40:27.037 回答