我对验证实体中的值的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;
}
现在我想只有实体类型“父”可能是父母。我可以用两种方式做到。
使用Symfony Callback validation:
if($ this-> getParent()!= null&& $ this-> getParent() - > getType()!='group') $ context-> addViolationAt('parent','Invalid parent。',array(),null);
这很明显,但只有在我调用验证器或
时才有效
中提出的那样
您应该检查生成的实体并根据自己的需要调整getter / setter逻辑
setParent(File $parent) {
if ($parent->getType() != 'group')
throw new \Exception('Invalid parent');
$this->parent = $parent;
}
哪种方法更好?使用专门为此目的创建的验证约束或getter和setter? 如果使用验证 - 我应该总是使用默认的getter和setter,还是我可以在其中做任何花哨的(和有用的)事情(任何例子)?
答案 0 :(得分:2)
我会首先使用Symfony回调验证,因为它是用于验证实体的专用构造,因为您的示例更接近用于回调验证的组件的设计理念。
虽然PHP OOP书籍确实鼓励您不仅使用getter和setter来检索属性值,但我总是使用它们来确保字段的默认值和约束(即我有一个 $ id < / strong>属性,类型为 int ,我想确保在设置时将 $ id 的值强制转换为 int 它,即使有人错误地发送了一个字符串/无论如何)。
除此之外,我还认为为setter设置try / catch块是很奇怪的,特别是当我知道我正在发送正确的参数类型时。
更新:刚刚注意到问题的最后部分。我使用我的Symfony getter和setter基本上只是为了检索/存储值。我倾向于为构造函数中的东西设置默认值。多年来我看到了一些代码,其中getter和setter做了一些非常疯狂的事情,它们实际上不属于实体的范围,而是更接近服务或存储库。
我认为实体是允许我将数据库表映射到PHP类的构造 - 它们不需要是智能,特殊或者在该范围之外做任何事情。
我更喜欢保持简单,并使用架构的其余部分来补充可能的操作。它是否能提供一些通用功能并且可以独立隔离?为此提供服务。它与操纵实体,检索某些信息或以特定方式处理它们有关吗?为此建立一个存储库。