2012-03-17 89 views
7

我希望能夠更改和傳遞UserEntity的某些部分,並且某些部分應保持不變。將域實體的可變屬性作爲​​值對象存儲可以嗎?

例如,我永遠不想更改我的UserEntity的id,但是電子郵件或密碼等內容可能會經常更改,也可能被UserEntity之外的其他對象使用。

創建UserEntity時會有一個實例。由於UserEntity不能存在沒有id,我的控制器可以創建一個UserData對象來標準化UserEntity屬性。在映射器在數據庫中創建一個實體之後,它將創建一個新的UserEntity並在構造函數中傳入id和UserData對象。

當UserEntity需要電子郵件或密碼等信息時,只需查看其UserData即可。

似乎更便攜,但這是矯枉過正?有更好的解決方案嗎?

注意

  • 之所以我認爲這可能是好:可變字段的值需要標準化......有時需要圍繞實體以外的地方通過這些領域本身。例如,在實體創建之前。通過創建一個可以傳遞的值對象,我們提供了一個標準化的點來從任何地方分配這些值,以及可以在實體外傳遞的東西。

  • 「標準化」我的意思是我的信息需要統一,無論它存在於何處。例如,email需要始終爲n長度和有效格式,name總是需要是n長度等。我的目標是我希望能夠在單個點中設置這些「規則」。並且由於UserEntity的這些屬性(可變屬性)存在於實體本身之外,有時它們可​​能獨立存在於它們自己的價值對象中。

+0

對我來說聽起來不錯:)據推測,你的ID字段是私人的,並且只有在你的UserEntity中獲得()訪問它...... – 2012-03-17 09:09:08

+0

這將是想法:)但是任何可變屬性的值設置器將在值對象。 – johnnietheblack 2012-03-17 17:17:50

+2

簡單地在實體對象上添加電子郵件,密碼和所有其他字段有什麼問題?有獨立的數據對象給予什麼好處? – 2012-03-20 13:05:27

回答

1

我不認爲這是「一個正確的方法」來做到這一點(不管你瞭解它是什麼)......如果它在你的模型是有道理的,那麼它聽起來不錯。當你說「許多這些領域需要標準化」,以及爲什麼不能作爲UserEntity的一部分來完成時,我不確定你的意思。也就是說,如果沒有完全獨立的對象類,你可以完成你想要做的事情。

評論/批評:

什麼,你所提出的建議並沒有真正附和嚴格的「對象」的模式,即的UserData是剛做起來的東西,真正的屬性UserEntity的,而且也沒有其他與這些屬性的基礎關係。

我真的不知道你爲什麼會需要一個單獨的對象是傳遞實體之外......如果你需要的數據,爲什麼你就不能繞過UserEntity,並從那裏訪問它?在將數據傳遞給UserEntity構造函數之前,您需要怎麼處理這些數據,而這些數據不能輕易地通過在stdClass的實例中收集數據然後在UserEntity中處理它來完成?


如果是我,我會做更多的東西一樣以下(,比如說,創建新用戶):

<? 
// assume an appropriately defined UserEntity class... 

// I'm using stdClass just to keep the parameters together to pass all at once 
// I'm assuming some basic user data passed from the browser 
$user_data = (object) array(
    'email' => $_REQUEST['email'], 
    'name' => $_REQUEST['name'], 
    'password' => $_REQUEST['password'], 
    'confirm_password' => $_REQUEST['confirm_password'] 
); 

/* 
validateData is static so it can be called before you create the new user 
It takes the $user_data object to validate and, if necessary, modify fields. 
It also takes a $create flag which indicates whether the data should be 
checked to make sure all of the necessary fields are there to create the user 
with. This allows you to call it on update with the $create flag unset and it 
will pass validation even if it's missing otherwise required fields. 
It returns $result, which indicates pass or failure, and the potentially modified 
$user_data object 
*/ 
$create = TRUE; 
list($result, $user_data) = UserEntity::validateData($user_data, $create); 

// equivalence allows you to pass back descriptive error messages 
if ($result === TRUE) { 
    // create the user in the database, get back $user_id... 
    $user = new UserEntity($user_id, $user_data); 
} 
else { 
    // return error to user 
} 

// access user data either individually, or if you want just make a getter 
// for the entire group of data, so you can use it just like you would a 
// separate UserData object 
send_double_opt_in($user->getUserData()); 
?> 

編輯,以解決更多的信息提供:

你說這些屬性存在於UserEntity之外,並且它們可能獨立存在......你的意思是這些屬性可以被收集,使用和丟棄,甚至不用於UserEntity o bject?如果是這種情況,那麼一個單獨的對象將完全適合該數據。如果不是,如果數據總是從屬於現有的或未來的用戶實體,那麼這些屬性將永遠不會「獨立存在」,我們稱之爲「全局數據」。如果將整個系統視爲一個整體,而不僅僅是代碼,那麼很可能數據「屬於」UserEntity類。對於靜態方法,我沒有看到特別的理由來避免它們(顯然),但是對於每一個他自己。許多其他體系結構會稍微複雜一些,但以下是一些選項:

  1. 驗證構造函數中的數據。問題是,如果它不驗證,你將不得不刪除數據庫條目。醜陋。
  2. 將數據庫交互和數據驗證一起移入構造函數。這可能會違反您首選的對象模型,您只需在創建對象後檢查對象的狀態(即設置一個公共屬性$this->status = 'error';或類似的東西來告訴您發生了某些必須處理的不良事件) 。
  3. 創建一個獨立的函數來驗證數據。醜陋,因爲這是一個與UserEntity和/或其數據特別相關的函數。
  4. 或者,只需創建一個單獨的UserData對象,就像您建議的一樣,並完成它。就像第二步一樣,你必須有某種$status屬性才能表明驗證失敗。
+0

感謝您的回答 - 爲了澄清,通過「標準化」我的意思是我的信息需要統一,無論它存在於何處。例如,電子郵件需要始終長度爲n,並且格式有效,名稱總是需要長度爲n等。我的目標(您實際上正在處理的是)我希望能夠設置這些「規則」在一個地方......並且由於UserEntity的這些屬性(可變屬性)存在於實體本身之外,有時它們可​​以獨立生活。 – johnnietheblack 2012-03-22 16:26:18

+0

這就是說,你只需要一個地方來驗證數據。然而,我傾向於迴避任何靜態函數......如果我要走這條路線,這實際上將是整個項目的第一個。有了我上面的評論,並且沒有靜態函數,你會提供任何修改嗎? – johnnietheblack 2012-03-22 16:27:40

+0

我已更新我的答案以反映新信息和偏好 – Jason 2012-03-22 17:37:26

0

看來,這可能是一組驗證器的好例子,它可以獨立於任何域對象使用 - 也許這是我的函數式編程端出來的,但我沒有看到問題通過創建一系列功能,如isValidEmail()

我知道你對一堆靜態函數感到不舒服,你會考慮一個靜態的Validator類而不是一堆方法,以保持整潔嗎? (無論哪種方式,您可以在UserEntity對象之外使用此驗證(我假定您正在討論類似其他域對象的情況,控制器中的輸入驗證等)。但是你也可以在'UserEntity'對象內部使用它 - 對於我自己,我還沒有確定在設置屬性或保存到持久存儲區時,我是否更喜歡衛生和驗證。我現在更傾向於通過二傳手功能傾向於第一。

相關問題