Archivo

Entradas Etiquetadas ‘Orientación a objetos’

PHP[DAO]::Data Access Object

Tuesday, 19 de August de 2008

El DAO, Data Access Object por sus siglas en inglés, corresponde a un patrón de diseño que tiene como proposito abstraer al software cliente del acceso a los datos o de la fuente de almacenamiento, y que solo se centre en los datos que necesite.

Este patrón de diseño nace de la necesidad de gestionar diversas fuentes de datos, aunque su uso se extiende al problema de encapsular no sólo la fuente de datos, sino que además mantiene oculta la forma en que se accede a los datos. Se trata de hacer que el software cliente se concentre en los datos que necesita y no se preocupe de cómo ni de dónde obtiene los datos.

El DAO realiza la implementacion del mecanismo para acceder a la fuente de datos, sea esta una base de datos, archivos externos, etc... Los componentes de negocio que tratan con el DAO utilizan un interface simple expuesto por el DAO para sus clientes. El DAO oculta completamente los detalles de implementación de la fuente de datos a sus clientes. Como el interface expuesto por el DAO no cambia cuando cambia la implementación de la fuente de datos subyacente, este patrón permite al DAO adaptarse a diferentes esquemas de almacenamiento sin que esto afecte a sus clientes o componentes de engocio. Esencialmente, el DAO actúa como un adaptador entre el componente y la fuente de datos.

Bueno, para que todo esto quede un poco más claro, voy a poner un ejemplo práctico sencillo para que se puedan formar una idea de como funciona. Si bien este patrón de diseño se puede aplicar a diversos lenguajes de programación, pondré el ejemplo en PHP, donde manipularemos datos de un "Usuario", no nos preocuparemos de la interfaz gráfica, sólo del manejo de datos.

[ UsuarioVO.php ] Clase usada para transportar informacion

PHP:
  1. require_once 'UsuarioVO.php';
  2.  
  3. class UsuarioVO
  4. {
  5. public $id;
  6. public $nombre;
  7. public $rut;
  8. public $username;
  9. public $bcryptpass;
  10. public $mail;
  11. public $region;
  12. public $sexo;
  13. public $telefono;
  14. public $descripcion;
  15. }
  16. ?>

[ UsuarioDAO.php ] Interface donde declaramos los metodos disponibles

PHP:
  1. interface UsuarioDAO
  2. {
  3. public function guardar($usuario_vo);
  4. public function buscarId($id);
  5. public function buscarCampo($campo, $valor);
  6. }
  7. ?>

[ Usuario_DB_DAO.php ] La clase que hace todo el trabajo

PHP:
  1. require_once 'UsuarioDAO.php';
  2. require_once 'UsuarioVO.php';
  3. require_once 'DB.php';
  4.  
  5. class Usuario_DB_DAO implements UsuarioDAO
  6. {
  7. private $conexion;
  8.  
  9. public function __construct()
  10. {
  11. // vamos a conectarnos...
  12. $this->conexion =
  13. DB::connect("mysql://root@localhost/mibase");
  14. $this->conexion->setFetchMode(DB_FETCHMODE_ASSOC);
  15. if (DB::isError($this->conexion)) {
  16. print "Fallo la conexion!";
  17. print "Error : " .
  18. $this->conexion->getMessage() . "";
  19. print "Detalles Error : " .
  20. $this->conexion->getUserInfo() . "";
  21. exit(1);
  22. }
  23. }
  24.  
  25. public function guardar($usuario_vo)
  26. {
  27. //  tenemos 2 casos.... insertar y actualizar
  28. if ( $usuario_vo->id == null ){
  29. $this->insertar($usuario_vo);
  30. }
  31. else {
  32. $this->actualizar($usuario_vo);
  33. }
  34. }
  35.  
  36. private function insertar(UsuarioVo $usuario_vo)
  37. {
  38. $sql = "INSERT INTO usuarios ".
  39. "(id, nombre, rut, username, bcryptpass,".
  40. "mail, region, sexo, telefono, descripcion) ".
  41. " VALUES ".
  42. " (?, ?, ? , ?, ? , ? , ?,  ?, ?, ?); ";
  43. // Antes de continuar vamos a obtener el nuevo id
  44. // Como estamos usando DB vamos a usar el mecanismo
  45. // propio de DB para obtener el id.
  46. $usuario_vo->id = $this->conexion->nextId("usuarios");
  47. $datos = array( $usuario_vo->id,
  48. $usuario_vo->nombre,
  49. $usuario_vo->rut,
  50. $usuario_vo->username,
  51. $usuario_vo->bcryptpass,
  52. $usuario_vo->mail,
  53. $usuario_vo->region,
  54. $usuario_vo->sexo,
  55. $usuario_vo->telefono,
  56. $usuario_vo->descripcion );
  57. $preparedStatement = $this->conexion->prepare($sql);
  58. $resultado =& $this->conexion->execute(
  59. $preparedStatement,$datos);
  60. if (PEAR::isError($resultado)){
  61. echo 'Falló la insercion en la BD ';
  62. echo $resultado->getMessage() . "";
  63. echo "Detalles Error : " .
  64. $resultado->getUserInfo() . "";
  65. }
  66. }
  67.  
  68. private function actualizar(UsuarioVo $usuario_vo)
  69. {
  70. $sql = "UPDATE usuarios SET ".
  71. "nombre = ? , ".
  72. "rut = ? , ".
  73. "username = ? , ".
  74. "bcryptpass = ? , ".
  75. "mail = ? , ".
  76. "region = ? , ".
  77. "sexo = ? , ".
  78. "telefono = ? , ".
  79. "descripcion = ?  ".
  80. "WHERE ".
  81. "id = ? ;";
  82. // Antes de continuar vamos a obtener el nuevo id
  83. // Como estamos usando DB vamos a usar el mecanismo
  84. // propio de DB para obtener el id.
  85.  
  86. $datos = array( $usuario_vo->nombre,
  87. $usuario_vo->rut,
  88. $usuario_vo->username,
  89. $usuario_vo->bcryptpass,
  90. $usuario_vo->mail,
  91. $usuario_vo->region,
  92. $usuario_vo->sexo,
  93. $usuario_vo->telefono,
  94. $usuario_vo->descripcion,
  95. $usuario_vo->id );
  96. $preparedStatement = $this->conexion->prepare($sql);
  97. $resultado =& $this->conexion->execute(
  98. $preparedStatement,$datos);
  99. if (PEAR::isError($resultado)){
  100. echo 'Falló la modificación en la BD ';
  101. echo $resultado->getMessage() . "";
  102. echo "Detalles Error : " .
  103. $resultado->getUserInfo() . "";
  104. }
  105. }
  106.  
  107. public function buscarId($id)
  108. {
  109. $sql = "SELECT * FROM usuarios WHERE id = ?";
  110. $preparedStatement = $this->conexion->prepare($sql);
  111. $resultado =& $this->conexion->execute(
  112. $preparedStatement,$id);
  113. if (PEAR::isError($resultado)){
  114. echo 'Falló la modificación en la BD ';
  115. echo $resultado->getMessage() . "";
  116. echo "Detalles Error : " .
  117. $resultado->getUserInfo() . "";
  118. }
  119. else if ($fila =& $resultado->fetchRow() ){
  120. $usuario_vo = new UsuarioVO();
  121. $usuario_vo->id = $fila['id'];
  122. $usuario_vo->nombre = $fila['nombre'];
  123. $usuario_vo->rut = $fila['rut'];
  124. $usuario_vo->username = $fila['username'];
  125. $usuario_vo->bcryptpass = $fila['bcryptpass'];
  126. $usuario_vo->mail = $fila['mail'];
  127. $usuario_vo->region = $fila['region'];
  128. $usuario_vo->sexo = $fila['sexo'];
  129. $usuario_vo->telefono = $fila['telefono'];
  130. $usuario_vo->descripcion = $fila['descripcion'];
  131. return $usuario_vo;
  132. }
  133. // Si hubo un error, o no encontramos nada...
  134. return null;
  135. }
  136.  
  137. public function buscarCampo($campo, $valor)
  138. {
  139. $sql = "SELECT * FROM usuarios WHERE $campo = ?";
  140. $preparedStatement = $this->conexion->prepare($sql);
  141. $resultado =& $this->conexion->execute(
  142. $preparedStatement,$valor);
  143. if (PEAR::isError($resultado)){
  144. echo 'Falló la modificación en la BD ';
  145. echo $resultado->getMessage() . "";
  146. echo "Detalles Error : " .
  147. $resultado->getUserInfo() . "";
  148. return null;
  149. }
  150. $respuesta = array();
  151. while ($fila =& $resultado->fetchRow() ){
  152. $usuario_vo = new UsuarioVO();
  153. $usuario_vo->id = $fila['id'];
  154. $usuario_vo->nombre = $fila['nombre'];
  155. $usuario_vo->rut = $fila['rut'];
  156. $usuario_vo->username = $fila['username'];
  157. $usuario_vo->bcryptpass = $fila['bcryptpass'];
  158. $usuario_vo->mail = $fila['mail'];
  159. $usuario_vo->region = $fila['region'];
  160. $usuario_vo->sexo = $fila['sexo'];
  161. $usuario_vo->telefono = $fila['telefono'];
  162. $usuario_vo->descripcion = $fila['descripcion'];
  163. $respuesta[] = $usuario_vo;
  164. }
  165. return $respuesta;
  166. }
  167. }
  168. ?>

Bien, ahora ya tenemos listas las clases que necesitamos para manipular nuestro usuario (los datos del usuario, no es que cumplamos es sueño de todo HelpDesk). Ahora solo nos falta alguien que necesite agregar, actualizar o borrar informacion del usuario.

Alguien que necesite ingresar un usuario...

[ InsertarUsuario.php ] Clase que insertará un usuario

PHP:
  1. require_once 'usuarioVO.php';
  2. require_once 'Usuario_DB_DAO.php';
  3.  
  4. // para probar, necesitamos crear un usuarioVO
  5.  
  6. $vo = new UsuarioVO();
  7. $vo->id = null;
  8. $vo->nombre = 'Juan Lopez';
  9. $vo->rut = '3-5';
  10. $vo->username = 'juanito';
  11. $vo->mail = 'juan.lopez@mimail.com';
  12. $vo->region = 13;
  13. $vo->telefono = '98765432';
  14. $vo->sexo = 1; // 1 hombre, 2 mujer!
  15. $vo->descripcion = 'Ejecutivo joven, baila salsa';
  16. $vo->bcryptpass = 'erwrwesdsdfsdfsdksd';
  17.  
  18. // Y necesitamos un dao...
  19. $dao = new Usuario_DB_DAO();
  20. $dao->guardar($vo);
  21. echo 'Terminamos!';
  22. ?>

Alguien que modifique un usuario...

[ ModificarUsuario.php ] Modificaremos un campo del usuario.

PHP:
  1. require_once 'usuarioVO.php';
  2. require_once 'Usuario_DB_DAO.php';
  3.  
  4. $dao = new Usuario_DB_DAO();
  5. $vo = $dao->buscarId(1);
  6.  
  7. echo 'Terminamos la busqueda';
  8. $vo->descripcion = $vo->descripcion. 'Probando modificar';
  9.  
  10. $dao->guardar($vo);
  11.  
  12. echo 'Terminamos!';
  13. ?>

Buscaremos usuarios que cumplan un cierto filtro o requisito...

[ BuscarCampo.php ] Buscaremos por un campo en específico.

PHP:
  1. require_once 'usuarioVO.php';
  2. require_once 'Usuario_DB_DAO.php';
  3.  
  4. $dao = new Usuario_DB_DAO();
  5. // buscamos a los hombres.
  6. $lista = $dao->buscarCampo('sexo', 1);
  7.  
  8. echo 'Hay '. count($lista). ' hombres registrados';
  9.  
  10. echo 'Terminamos!';
  11. ?>

Una simple búsqueda por ID, y listaremos todos sus valores...

[ BuscarPorID.php ] Buscaremos por un ID.

PHP:
  1. require_once 'usuarioVO.php';
  2. require_once 'Usuario_DB_DAO.php';
  3.  
  4. $dao = new Usuario_DB_DAO();
  5. $vo = $dao->buscarId(1);
  6.  
  7. // Obs tratamos el objeto como un arreglo
  8. foreach($vo as $llave => $valor){
  9. echo "$llave : $valor ";
  10. }
  11. echo 'Terminamos la busqueda';
  12. ?>

Ya, terminamos este simple ejemplo de como funciona el DAO, espero esté redactado de forma clara y comprensible.

Toda crítica o comentario será bienvenida...

VN:F [1.0.9_379]

Ancelot PHP, Programación , , , , , , ,