2012-03-17 18 views
7

Hay ciertas partes de UserEntity que me gustaría poder cambiar y transmitir, y hay ciertas partes que deben permanecer constantes.¿Está bien almacenar las propiedades mutables de una entidad de dominio como un objeto de valor?

Por ejemplo, NUNCA quiero cambiar mi ID de UserEntity, pero cosas como el correo electrónico o la contraseña pueden cambiar a menudo y también pueden ser utilizados por otros objetos fuera de UserEntity.

Una instancia de esto sería cuando se crea una UserEntity. Como UserEntity no puede existir sin una identificación, mi controlador podría crear un objeto UserData que estandarizaría las propiedades UserEntity. Después de que el asignador cree una entidad en el archivo db, creará una nueva UserEntity y pasará el identificador y el objeto UserData en el constructor.

Cuando UserEntity necesita información como el correo electrónico o la contraseña, solo puede ver su UserData.

Parece más portátil, pero ¿es esto exagerado? ¿Hay una mejor solución?

Nota

  • La razón por la que creo que esto podría ser bueno: los valores de los campos variables necesitan ser estandarizadas ... y, a veces estos campos tienen que pasar por el exterior de la entidad sí mismo. Por ejemplo, antes de que la entidad haya sido creada. Al crear un objeto de valor que se puede pasar, proporcionamos un lugar estandarizado para asignar estos valores desde cualquier lugar, así como también algo que se puede pasar fuera de la entidad.

  • Por "estandarizar" me refiero a que mi información debe ser uniforme, donde sea que exista. Por ejemplo, email necesita ser siempre n de longitud y en un formato válido, name siempre debe ser n longitud, etc. Mi objetivo aquí es que me gustaría poder establecer esas "reglas" en un solo lugar .. .y dado que estas propiedades de la UserEntity (las mutables) existen fuera de la propia entidad, a veces, podrían vivir por sí mismas, en su propio objeto de valor.

+0

me suena bien :) presumiblemente, su campo ID es privado y solo hay acceso get() a él dentro de UserEntity ... –

+0

Esa sería la idea :) sin embargo cualquier valor setters para las propiedades mutables estaría en el objeto de valor – johnnietheblack

+2

¿Qué tiene de malo simplemente tener correo electrónico, contraseña y todos los demás campos en el objeto de entidad? ¿Qué beneficios ofrece tener objetos de datos separados? –

Respuesta

1

No creo que hay "un verdadero camino" para hacerlo (no importa lo que se lee al respecto) ... si tiene sentido en el modelo, entonces me parece bien. No estoy seguro de a qué se refiere exactamente cuando dices "muchos de esos campos deben estandarizarse" y por qué no se pudo hacer como parte de UserEntity, pero lo que sea. Dicho esto, lo más probable es que puedas lograr exactamente lo que intentas hacer sin una clase de objeto completamente separada.

Comentarios/Críticas Diarios:

Lo que está sugiriendo realmente no estar de acuerdo con un modelo estricto "objeto", es decir, el UserData es sólo hecha de cosas que son realmente atributos de UserEntity, y no hay otra relación subyacente a esos atributos.

No estoy muy seguro de por qué necesitaría un objeto separado para pasar fuera de la entidad ... si necesita los datos, ¿por qué no puede pasar el UserEntity y acceder desde allí? ¿Qué necesita hacer con los datos antes de pasarlos al constructor UserEntity que no podrían lograrse tan fácilmente reuniendo los datos en una instancia de stdClass y luego procesándolos en UserEntity?


Si fuera yo, me gustaría hacer algo más parecido a lo siguiente (para, por ejemplo, la creación de un nuevo usuario):

<? 
// 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()); 
?> 

Editar para abordar más información:

Dice que estas propiedades existen fuera de UserEntity, y que potencialmente podrían vivir solas ... ¿Quiere decir que estas propiedades podrían reunirse, usarse y descartarse sin siquiera estar destinadas a UserEntity o bject? Si ese es el caso, entonces un objeto separado sería completamente apropiado para esa información. De lo contrario, si los datos están siempre subordinados a una UserEntity existente o futura, esas propiedades nunca "vivirán por su cuenta" desde un ... vamos a llamarlo un punto de vista de "datos globales". Cuando considera el sistema completo como un todo, no solo el código de momento a momento, es probable que los datos "pertenezcan" a la clase UserEntity.

En cuanto a los métodos estáticos, no veo ninguna razón particular para evitarlos (obviamente), pero cada uno es suyo. Muchas otras arquitecturas serían un poco más complejas, pero he aquí algunas opciones:

  1. Validar los datos en el constructor. El problema es que si no valida, deberá eliminar la entrada de la base de datos. Feo.
  2. Mueva la interacción de la base de datos al constructor, junto con la validación de datos. Esto podría violar el modelo de objeto preferido y solo deberá verificar el estado del objeto una vez creado (es decir, establecer una propiedad pública $this->status = 'error'; o algo así para decirle que sucedió algo malo que deberá manejar) .
  3. Crea una función independiente para validar los datos. Feo, porque esta es una función que está específicamente relacionada con UserEntity y/o sus datos.
  4. O bien, simplemente cree un objeto UserData separado como lo sugirió y termine con él. Al igual que en el paso 2, deberá tener algún tipo de propiedad $status para indicar una validación fallida.
+0

Gracias por la respuesta, así que para aclarar, al "estandarizar" me refiero a que mi información debe ser uniforme, donde sea que exista. Por ejemplo, el correo electrónico tiene que ser siempre 'n' de longitud y en un formato válido, el nombre siempre debe ser' n' de longitud, etc. Mi objetivo aquí (que realmente abordas) es que me gustaría ser capaz de establecer esas "reglas" en un solo lugar ... y dado que estas propiedades de la UserEntity (las mutables) existen fuera de la entidad misma, a veces, potencialmente podrían vivir por sí mismas. – johnnietheblack

+0

Dicho esto, se dirige a un solo lugar para validar los datos. Sin embargo, tiendo a alejarme de cualquier función estática ... este sería en realidad el primero del proyecto completo, si tuviera que seguir esta ruta. Con mi comentario anterior, y sin una función estática, ¿ofrecerías alguna modificación? – johnnietheblack

+0

He actualizado mi respuesta para reflejar la nueva información y preferencias – Jason

0

Parece que este sería un buen caso para un conjunto de validadores que se pueden usar independientemente de cualquier objeto de dominio; quizás este sea mi lado de programación funcional que sale, pero no veo un problema con la creación de un conjunto de funciones como isValidEmail().

Entiendo que no se siente cómodo con un montón de funciones estáticas; ¿consideraría una clase estática Validator con un montón de métodos en su lugar, para mantener las cosas ordenadas?

De cualquier forma, podría usar esta validación fuera del objeto UserEntity (supongo que está hablando de casos como otros objetos de dominio, validación de entrada en el controlador, etc.). Pero también podría usarlo dentro del objeto 'UserEntity' - para mí, aún no he determinado si prefiero la sanitización y la validación cuando se establece una propiedad, o cuando se guarda en la tienda persistente. Actualmente me inclino más hacia el primero, a través de las funciones del colocador.

Cuestiones relacionadas