2011-01-30 11 views
22

Pregunta extendida: ¿Por qué debería usar data mapper/Db_Table_Row, donde como DbTable es capaz de manejar la mayoría de las tareas básicas para la manipulación de datos?Zend framework - ¿Por qué debería usar data mapper/Db_Table_Row?

Actualmente estoy aprendiendo ZF v1.11

Para la manipulación de bases de datos, creé DbTable para cada tablas. Por ejemplo, la tabla de "usuarios" está representada por Application_Model_DbTable_Users sin códigos adicionales allí.

Cuando la manipulación de datos, que puede utilizar:

<?php 
$uTable = new Application_Model_DbTable_Users(); 
$newUid = $uTable->insert(array('name'=>'Old Name', 'email'=>'')); 
$user = $uTable->find($newUid)->current(); 

// Then I can use $user which is instance of Table_Row 
$user->name = "New Name"; 
$user->email = "[email protected]"; 
$user->save(); 

Mi pregunta es, cuando voy a necesitar para definir una clase fila (suponiendo Table_Row se conoce como DataMapper en ZF-tutoriales)

// By, adding this to the DbTable class 
protected $_rowClass = 'Application_Model_User'; 

¿Cuáles son los beneficios de tener una clase Row para cada entidad? ¿Alguien puede señalarme las mejores prácticas para esto?

+0

http://stackoverflow.com/questions/373054/ - da una idea de que, el envío de correo electrónico o la modificación de la contraseña de la lógica se puede implementar en la clase de la fila de tabla, que son específicos para el usuario. –

Respuesta

41

No necesita definir su propio Table_Row. Sin embargo, puede ser útil en muchos casos, especialmente si desea definir algunos métodos o propiedades específicos para una fila de usuario determinada. También pueden mejorar la legibilidad de tu código.

Por ejemplo en su caso tabla Usuarios, se podría definir un método llamado getFullName() en una fila de usuario personalizada como:

public function getFullName() { 
    return $this->firstName . ' ' . $this->lastName; 
} 

A continuación, cuando se obtiene objeto de fila del usuario, para obtener el nombre completo del usuario, que acaba de hacer:

$user = $uTable->find($newUid)->current(); 
$fullName = $user->getFullName(); 

Segundo ejemplo es cuando usted tiene alguna tabla primaria de la tabla Usuarios, tales como direcciones. En este caso se podría definir un método llamado GetAddress en una fila de usuario:

public function getAddress() { 
    return $this->findParentRow('Application_Model_DbTable_Addresses'); 
} 

En este escenario, se llega a un objeto fila Dirección para un usuario actual de la siguiente manera:

$user = $uTable->find($newUid)->current(); 
$addressRow = $user->getAddress(); 

Otro ejemplo, sería cuando desee crear métodos personalizados de eliminación o inserción. Supongamos que desea asegurarse de que no desea eliminar un usuario administrador mediante el método delete(). Posteriormente, se podría sobrecargar el método de eliminación de Zend_Db_Table_Row de la siguiente manera:

public function delete() { 
     if ('admin' === $this->userRole) { 
       return 0; 
     } 
     return parent::delete(); 
} 

De esta manera, no sería capaz de eliminar un usuario administrador simplemente llamando a delete() en un objeto de fila de usuario:

$user = $uTable->find($newUid)->current(); 
$rowsDeleted = $user->delete(); // would be 0 if $user is admin 

Estos son solo tres ejemplos básicos que muestran la utilidad de definir sus propias clases de filas. Pero, por supuesto, no son necesarios. Sin embargo, desde mi propia experiencia, son bastante útiles.

+0

¡¡¡Impresionante !!! Gracias por los códigos de ejemplo de la vida real con la explicación: -] –

+0

+1 De hecho, muy agradable. –

+0

En la respuesta de la pregunta # 373054, hay una función sendMailTo para el usuario, ¿es una buena práctica mantener las funciones no relacionadas con la base de datos en la clase Db_Row? ¿Dónde debería permanecer este tipo de lógica comercial específica para el usuario? –

20

En pocas palabras: se trata de aislamiento.

Zend_Db_Table es una implementación de Table Data Gateway. Canaliza el acceso de CRUD a una vista de tabla específica a través de una clase.Generalmente se usa con un Table Module, p. Ej. una clase que contiene la lógica comercial para los registros manejados por una puerta de enlace.

Zend_Db_Table_Row es una implementación del Row Data Gateway Pattern. Aquí, los objetos devueltos se ven exactamente como un registro de base de datos y contienen la lógica de negocio para trabajar con esos datos, pero no contienen la lógica para CRUD con la tabla de la que son (que sería un ActiveRecord) sino que los agregan.

Los gateways de datos de fila están bien siempre que no tenga demasiados object relational impedance mismatch. Cómo persiste un objeto en una base de datos relacional y cómo debería verse en un mundo de objetos a menudo son cosas muy diferentes. Al utilizar un Domain Model, sus objetos comerciales generalmente se estructuran de una manera diferente a como están almacenados en la base de datos. Por lo tanto, no puede CRUDARlos fácilmente de la base de datos. Aquí es donde entra en juego DataMapper.

Un DataMapper toma la responsabilidad de mapear objetos de dominio en Recordsets y viceversa. Esto hace que su aplicación sea más fácil de mantener porque desacopla sus objetos de dominio de la estructura de la base de datos. Los mantiene separados y le da más flexibilidad sobre cómo modelar ambas capas (persistencia y dominio).

Cuestiones relacionadas