2013-10-11 35 views
2

我有關於在實體中驗證值的OOP策略的問題。可以說我有這樣的實體:驗證實體中的值 - 通過setter或assert驗證?

/* 
* @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 Callback validation

    如果(!$這個 - >的getParent()= NULL & & $這個 - >的getParent() - >的getType()= '集團') $上下文> addViolationAt('parent','Invalid parent。',array(),null);

這是相當明顯的,但只能像它在Symfony book

之擬議當我打電話驗證,或

  1. 把這個邏輯在二傳手應檢查產生的實體和根據您自己的需要調整獲取/設置邏輯
例如:

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

哪種方法比較好?使用專門爲此目的創建的驗證約束條件還是獲取者和設置者? 如果使用驗證 - 我應該總是使用默認的getter和setters,還是他們可以在裏面做任何奇特(而且有用)的東西(任何例子)?

回答

2

我會使用Symfony回調驗證,首先關閉,因爲它是驗證實體的專用構造,因爲您的示例更接近用於回調驗證的組件的設計原理。儘管PHP OOP書籍確實鼓勵您不僅使用getter和setter來檢索屬性值,但我一直使用它們來確保字段上的默認值和約束(即,我有一個$ id屬性,它的類型是int,並且我想確保在設置它時將$ id的值轉換爲int,即使有人錯誤地發送了字符串/無論如何)。

除此之外,我還認爲爲setter設置try/catch塊會很奇怪,特別是當我知道我使用正確的參數類型發送數據時。

更新:剛剛注意到你的問題的最後部分。我使用我的Symfony getter和setter基本上只是爲了檢索/存儲值。我傾向於在構造函數中爲事物設置默認值。多年來,我已經看到了一些代碼,其中getter和setter做了一些非常狂野的事情,這些代碼實際上不屬於實體的範圍,而更接近於Service或Repository。

我認爲實體作爲允許我將數據庫表映射到PHP類的構造 - 它們不需要是智能,特殊的,或者在該範圍之外做任何事情。

我更喜歡保持簡單,並使用其餘的體系結構來補充可能的操作。它是否提供了一些通用功能,並且可以獨立分離?爲此提供服務。這與處理實體,檢索某些信息或以特定方式處理它們有關嗎?爲此創建一個存儲庫。