Foros del Web » Programando para Internet » PHP » Frameworks y PHP orientado a objetos »

Object Oriented en la cruda realidad

Estas en el tema de Object Oriented en la cruda realidad en el foro de Frameworks y PHP orientado a objetos en Foros del Web. Por mucho que busco no encuentro ejemplos reales de programación OO, todo son simples ejemplos de una clase muy básica. Pero si nos remitimos a ...
  #1 (permalink)  
Antiguo 19/08/2011, 04:25
 
Fecha de Ingreso: agosto-2011
Mensajes: 3
Antigüedad: 13 años, 4 meses
Puntos: 3
Object Oriented en la cruda realidad

Por mucho que busco no encuentro ejemplos reales de programación OO, todo son simples ejemplos de una clase muy básica. Pero si nos remitimos a la realidad, nos topamos con diferentes problemas. A ver si alguien me da luz.

Pongo en antecedentes y luego pregunto. En cualquier website tenemos usuarios, en mi caso, ademas, hay empleados, clientes y proveedores.

Mi primera duda es como manejar estos "objetos".
La opcion A es crear una classe por cada tipo, clase usuarios, clase empleados, clase ...
La opcion B es crear una clase "Persona" con nombre, apellidos, ... y luego derivadas de ésta, clases Empleados, Usuarios, Clientes ...
La opción C es una clase que engloba a todos y tiene la propiedad "tipo" en donde especificas si es un empleado, usuario, etc.

Esta claro que cada tipo tiene algun atributo diferente, por ejemplo un empleado puede tener datos personales que un usuario no tiene. Según la teoría de programacion OO ¿ como debería programarlo ? A, B, C, D?????

Vale, ahora vamos a la segunda parte. Nos quedamos con la clase User y nos olvidamos de Empleados, Clientes ...
Un usuario se guarda en la tabla Usuarios de la BD. Supongo que de alguna forma debería heredar de otra clase cómo guardar y extraer la info de la BD. En el fondo haríamos algo como User->LoadByNick("nickname"), o bien User->Save()

¿ como hacerlo independiente de tipo de BD o formato ? Si en vez de usar Mysql quisiera grabar en un fichero ascii ? Debería heredar ? o bien obtener de una variable mas global el objeto "storage" y que este manejara si es una BD o un fichero ascii ...

Por último, continuando con la clase User. Imagina que hago una página que lista usuarios y hay un filtro por nick, puedes ver todos los usuarios o buscar los que contengan unos caracteres escritos por los usuarios.

Teniendo en cuenta que la clase User sólo contiene la información de un usuario ¿ hay que hacer una clase por encima que sea UsersList ? me explico, si creamos una clase con UsersList, con la funcion GetAll y la funcion FilterByNick("aaa").
Si es este caso: entendria de usar algo como Next() para recuperar el siguiente usuario y devolver el objeto User para imprimir el nombre y la fecha del último acceso.

Pero esto último me lleva a varios problemillas:
- Tanto la clase User como la Clase UsersList deben conocer como trabajar con la tabla Users.
- Si UsersList accede a la BD, entonces habria que crear un metodo de rellenar el objeto User a partir de los datos de Userlist.
- Si sólo necesito 2 campos de los 20, es un desperdicio de tiempo y recursos tener que coger siempre toda la información.

Gracias a todos.
  #2 (permalink)  
Antiguo 19/08/2011, 04:40
Avatar de OsSk4R  
Fecha de Ingreso: octubre-2006
Ubicación: $this->home
Mensajes: 824
Antigüedad: 18 años, 2 meses
Puntos: 74
Respuesta: Object Oriented en la cruda realidad

Buenas,
En primer lugar yo creo que esta pregunta debería ir en el foro OOP.

En segundo lugar, voy a dar mi simple opinión como novato de la OOP :P así que mil disculpas si no es acertada.

De las opciones, yo elegiría la opción B o C. Son las que cumplen según mi parecer con la OOP.
Aunque creo que me quedaría con la opción B. ¿Me equivoco? Qué algun experto responda :P


Cita:
Vale, ahora vamos a la segunda parte. Nos quedamos con la clase User y nos olvidamos de Empleados, Clientes ...
Un usuario se guarda en la tabla Usuarios de la BD. Supongo que de alguna forma debería heredar de otra clase cómo guardar y extraer la info de la BD. En el fondo haríamos algo como User->LoadByNick("nickname"), o bien User->Save()

¿ como hacerlo independiente de tipo de BD o formato ? Si en vez de usar Mysql quisiera grabar en un fichero ascii ? Debería heredar ? o bien obtener de una variable mas global el objeto "storage" y que este manejara si es una BD o un fichero ascii ...
Con PDO o adodb puedes hacer que tu código trabaje para MySQL, Postgre, etc.


Cita:
Teniendo en cuenta que la clase User sólo contiene la información de un usuario ¿ hay que hacer una clase por encima que sea UsersList ?
La clase User debería de tener todo lo concerniente a un usuario. Sus datos personales, actividad, etc. Luego, podrías crear una clase llamada Usuarios, que sirva a nivel general y, ahí, introducir métodos como por ejemplo listar todos los usuarios, filtrar por X, etc.

Un saludo,
  #3 (permalink)  
Antiguo 19/08/2011, 06:21
Avatar de Ronruby  
Fecha de Ingreso: julio-2008
Ubicación: 18°30'N, 69°59'W
Mensajes: 4.879
Antigüedad: 16 años, 5 meses
Puntos: 416
Respuesta: Object Oriented en la cruda realidad

Yo iria por la 2da opcion. Crear la clase Persona como clase Padre de los demas tipos de usuarios.
Cita:
Vale, ahora vamos a la segunda parte. Nos quedamos con la clase User y nos olvidamos de Empleados, Clientes ...
Un usuario se guarda en la tabla Usuarios de la BD. Supongo que de alguna forma debería heredar de otra clase cómo guardar y extraer la info de la BD. En el fondo haríamos algo como User->LoadByNick("nickname"), o bien User->Save()

¿ como hacerlo independiente de tipo de BD o formato ? Si en vez de usar Mysql quisiera grabar en un fichero ascii ? Debería heredar ? o bien obtener de una variable mas global el objeto "storage" y que este manejara si es una BD o un fichero ascii ...
Primero, la clase User no debe interactuar con la base de datos. Lo mejor seria usar un patron de diseno llamado Data Access Object. Utilizando ese patron de diseno tambien aislas tu base de datos, asi es mas facil cambiar entre una y otra sin ningun cambio invasivo en tu codigo ya creado.

En cuanto a tu otra duda, no comprendo bien a lo que te refieres.
  #4 (permalink)  
Antiguo 19/08/2011, 06:58
Avatar de CesarHC  
Fecha de Ingreso: junio-2011
Ubicación: localhost
Mensajes: 566
Antigüedad: 13 años, 6 meses
Puntos: 56
Respuesta: Object Oriented en la cruda realidad

Yo recien llevo un tiempo en eso, yo uso la primera opcion tengo un clase usuarios,clientes,etc. en las que defino el guardar, modificar,etc. y llamo esas clases al formulario, cual es la diferencia entre esta opcion y la segunda?
__________________
Solo la práctica no te traicionara ¡¡¡¡¡¡

Seguir el camino tu debes PHP The Right Way.
  #5 (permalink)  
Antiguo 19/08/2011, 07:30
Avatar de jotaincubus  
Fecha de Ingreso: mayo-2005
Ubicación: Medellin - Colombia
Mensajes: 1.797
Antigüedad: 19 años, 7 meses
Puntos: 394
Respuesta: Object Oriented en la cruda realidad

Bueno amigo, lo que tu dices no tiene nada de raro, cuando empece con la POO me encontre con dilemas iguales a los tuyos y acudí a muchos programadores y cada uno de ellos tenia una idea diferente de como manejar las clases en una aplicación.

Pero de todos las personas a las cuales acudí las mejores respuestas me las brindaron los usuarios mas experimentados como son Abimael, Pateke, Masterpupet y otros...

Se trata de un patron de diseño llamado SINGLETON

Lo otro a tener en cuenta es el patrón de diseño con UML el cual para mi es la BASE PRIMORDIAL cuando se quiere empezar a manejar desarrollo con POO

Espero que la info que te brindo te saque un poco de la duda que tenes, ya que en realidad antes de ponerse a desarrollar como loco uno debe empezar por hacer el diseño UML y así veras que la POO no es tan difícil ni es una "CRUDA REALIDAD"...

Cita:
EDIT: No puedo dejar pasar por alto la GRANDISIMA ayuda que me ha dado Ronruby que es una persona que admiro por el gran conocimiento que tiene acerca de la programación.
__________________
Por que existe gente que no agradece después de que se le ha brindado tiempo y ayuda ???

Última edición por jotaincubus; 19/08/2011 a las 07:39
  #6 (permalink)  
Antiguo 19/08/2011, 07:45
 
Fecha de Ingreso: agosto-2011
Mensajes: 3
Antigüedad: 13 años, 4 meses
Puntos: 3
Respuesta: Object Oriented en la cruda realidad

Ok. Gracias por vuestros comentarios. Deduzco que se hace como cada uno le venga en gana.
Analizando y buscando a fondo, y teniendo como referencia buena este enlace de IBM http://www.ibm.com/developerworks/xml/library/os-php-flexobj/ , creo, deduzco que la programacion OO en estos casos debería ser la opción B:

class Persona {
$id
$nombre
$direccion
$foto
...
}

class Usuario extends Persona {
$nick
$password
...
}

class Cliente extends Persona {
$direccion_entrega
$habitual
...
}

Para la implementación de una BD o similar, creo que debería ser un wrapper a un PDO o AdoDB o cualquier cosa algo como:

class Storage extends PDO {
Insert()
Update()
Delete()
}

de esta forma, puedo utilizar cualquier implementación de BD, o de sockets, o de cualquier modo de guardar información. Supongo en que en fondo sería:

class Persona extends Storage {
Insert() {
...
parent::Insert(...);
...
}
}


Pero me queda la tercera, que aun dudo como hacerlo en el concepto de OO. Si yo quiero listar todos los clientes que tengo puedo hacerlo de la forma A ó B:

a)
class Clientes {
Query(...) { Storage->Query("SELECT * FROM Clientes ..." }
Next() {
...
$Cliente = new Cliente(id)
...
return $Cliente
}

}

b)
class Cliente extends Persona {
$direccion_entrega
$habitual
...
Query() {}
Next() {
$this->id = storage->id;
$this->name = storage->name;
...
}


De la forma a) no me gusta que Clientes acceda a la BD independiente de Cliente
De la forma b) no me gusta aplicar el concepto clientes si la clase es cliente.

Argh! Gracias de nuevo por vuestras aportaciones.
  #7 (permalink)  
Antiguo 19/08/2011, 10:32
Avatar de Ronruby  
Fecha de Ingreso: julio-2008
Ubicación: 18°30'N, 69°59'W
Mensajes: 4.879
Antigüedad: 16 años, 5 meses
Puntos: 416
Respuesta: Object Oriented en la cruda realidad

Cita:
Para la implementación de una BD o similar, creo que debería ser un wrapper a un PDO o AdoDB o cualquier cosa algo como:

class Storage extends PDO {
Insert()
Update()
Delete()
}

de esta forma, puedo utilizar cualquier implementación de BD, o de sockets, o de cualquier modo de guardar información. Supongo en que en fondo sería:

class Persona extends Storage {
Insert() {
...
parent::Insert(...);
...
}
}
En esta parte la herencia no es lo mas adecuado.

Una forma de saber si usar herencia o simplemente instanciar un objeto es haciendo lo siguiente:
Digamos que tienes 2 objetos, Persona y Cliente. Para determinar si usar herencia dices:
Cliente ES UN(A) Persona; esto tiene sentido.
Para determinar si debes instanciar el objeto dices:
Cliente TIENE UN(A) Persona; esto no tiene sentido.
En este caso, debes utilizar herencia.

Ahora con otros 2 objetos: ListaPersonas y ConexionDB
ConexionDB ES UN(A) ListaPersonas; no tiene sentido, tampoco lo contrario.
Sin embargo:
ListaPersonas TIENE UN(A) ConexionDB; esto tiene mas sentido.

Si entonces la herencia no es lo mas adecuado en este caso probablemente te preguntes, ¿que debo hacer en ese caso para no complicar mi diseño?

Yo lo haria de la siguiente manera:

Creo una clase abstracta llamada DAOFactory:
Código PHP:
public abstract class DAOFactory {
    
    
//Retorna una implementacion de PersonaDAO
    
public abstract getPersonaDAO();
    
//Retorna una implementacion de OtroDAO
    
public abstract getOtroDAO();
    
    
//Retorna una implementacion de DAOFactory
    
public static getDAOFactory(CONSTANTE) {
        case(
CONSTANTE) {
            case 
MySQLDAOFactory:
                return new 
MySQLDAOFactory();
                break;
            case 
OracleDAOFactory:
                return new 
OracleDAOFactory();
                break;
        }
    }
    
}

public interface 
PersonaDAO {
    public 
getPersonaById(int id);
    public 
getAllPersonas();
    public 
insertPersona(Persona $people);
}

public interface 
OtroDAO {
    public 
getOtroById(int id);
    public 
getAllOtros();
    public 
insertOtro(Otro $other);

Vamos al siguiente punto, ahora creamos implementaciones de esas clases e interfaces:

Código PHP:
public class MySQLDAOFactory extends DAOFactory {
    
//Debemos implementar los metodos abstractos:
    
public MySQLDAOFactory() {
        
//Inicializo mi clase, ya sea conectandome a la BD o lo que sea
    
}
    
    public static 
crearConexion() {
        
//Devuelvo un objeto de conexion
    
}
    
    public 
getPersonaDAO() {
        return new 
MySQLPersonaDAO();
    }
    
    public 
getOtroDAO() {
        return new 
MySQLOtroDAO();
    }
}

public class 
MySQLPersonaDAO implements PersonaDAO {
    
//Ahora implemento los metodos de la interface:
    
public getPersonaById(int $id) {
        
//Blah blah blah, llamo al metodo estatico crearConexion de MySQLDAOFactory
        //Obtengo el registor en la base de datos usando sintaxis MySQL
    
}
    public 
getAllPersonas() {
        
//Hago lo mismo que en el metodo anterior, solo que esta vez
        //devuelvo un listado de objetos Persona (en un array)
    
}
    public 
insertPersona(Persona $people) {
        
//Inserto la Persona a MySQL
    
}

Ya con esa parte del codigo se entiende la idea, asi que continuare.

Si en algun momento tengo que digamos insertar una Persona, haria algo como:
Código PHP:
$Persona = new Persona("Ronald""Castillo");

$DAOFactory DAOFactory.getDAOFactory(MySQLDAOFactory);
$PersonaDAO $DAOFactory->getPersonaDAO();
$PersonaDAO->insertPersona($Persona); 
Ahora es donde me diras: Dijiste que la idea no era complicarse.
Aunque parece complicado ahora, veamos la belleza de la POO cuando sometemos nuestra aplicacion a un cambio.

Si luego decides que no quieres usar MySQL, sino que quieres usar Oracle, el unico cambio que tendrias que hacer seria:
Código PHP:
$Persona = new Persona("Ronald""Castillo");

$DAOFactory DAOFactory::getDAOFactory(OracleDAOFactory);
$PersonaDAO $DAOFactory->getPersonaDAO();
$PersonaDAO->insertPersona($Persona); 
El codigo sigue igual, lo unico que cambio es la constante que le pasamos a getDAOFactory (Y talvez un cambio a la clase DAOFactory para agregar el nuevo motor de BD). Claro que probablemente esa parte del codigo este aislada para que solamente tengas que incluir ese archivo.
Con solo 1 CAMBIO, cambiaste la base de datos de MySQL a Oracle y tu codigo ni se entero. Nada dejará de funcionar.

PD: No te mostre las clases para Oracle, pero serian iguales que las de MySQL solo que el codigo para insertar seria diferente.

PD2: La libreria PDO te ayuda a separar tu base de datos de la logica de tu aplicacion para aminorar los cambios, te recomiendo que la uses.

PD3: Con otro patron de diseño llamado Dependency Injection fuera muchisimo mas facil aun, pero nunca he usado este patron en PHP, solo en Java

PD4: El codigo no correra, es solo un ejemplo para que te guies

Cita:
EDIT: No puedo dejar pasar por alto la GRANDISIMA ayuda que me ha dado Ronruby que es una persona que admiro por el gran conocimiento que tiene acerca de la programación.
Uy, gracias jotaincubus xD Nunca habia escuchado algo asi. Aunque aun me considero un novato.

Fuente: http://java.sun.com/blueprints/corej...essObject.html
+ muchisimos libros de programacion en Java
  #8 (permalink)  
Antiguo 19/08/2011, 16:12
Avatar de jahepi
Colaborador
 
Fecha de Ingreso: diciembre-2004
Ubicación: Querétaro
Mensajes: 1.124
Antigüedad: 20 años
Puntos: 43
Respuesta: Object Oriented en la cruda realidad

Hola drieran !

Aparte del ejemplo de Ronruby te pongo otro ejemplo de implementación de como puedes separar tu capa de acceso a datos con la capa de dominio.

Primero en tu capa de acceso a datos haremos una clase persona que se encargue de consultar la información de algún manejador de base de datos, llamaremos a esta clase "PersonaPersistencia":

Código php:
Ver original
  1. class PersonaPersistencia
  2. {
  3.     private $_db;
  4.    
  5.     public function __construct() {
  6.         $this->_db = new DB();
  7.     }
  8.    
  9.     public function obtenerPorId($id) {
  10.         return $this->_db->ejecutarSQL("SELECT * FROM personas WHERE id = $id");
  11.     }
  12.    
  13.     public function obtenerTodos() {
  14.         return $this->_db->ejecutarSQL("SELECT * FROM personas");
  15.     }
  16.    
  17.     public function insertar($nombre) {
  18.         return $this->_db->ejecutarSQL("INSERT...");
  19.     }
  20.    
  21.     public function actualizar($id, $nombre) {
  22.         return $this->_db->ejecutarSQL("UPDATE...");
  23.     }
  24. }

Como puedes ver tiene un atributo privado "db", que es un objeto de la clase DB que se encargaría de abstraer el acceso a los diferentes manejadores de base de datos, por ejemplo la clase DB podría hacer uso de PDO para conectarte a MySql, SQL Server, entre otros.
También puedes observar cada unos de los métodos públicos para consultar, insertar y actualizar la información con la ayuda de la instancia db.

La implementación de la clase DB no la he puesto para no complicarnos más de la cuenta, pero estoy seguro que captarás la idea.

Ahora si pasemos a ver la clase Persona, que contendrá cada uno de los atributos como id, nombre y edad, esta hará uso de la clase de persistencia para consultar, insertar y actualizar los datos necesarios.

Código php:
Ver original
  1. class Persona {
  2.    
  3.     private $_id;
  4.     private $_nombre;
  5.    
  6.     private static $_persistencia = new PersonaPersistencia();
  7.    
  8.     public function __construct() {
  9.     }
  10.    
  11.     public static function obtener($id) {
  12.         $dato = self::$_persistencia->obtenerPorId($id);
  13.         $persona = new Persona();
  14.         $persona->_id = $datos['id'];
  15.         $persona->_nombre = $datos['nombre'];
  16.         return $persona;
  17.     }
  18.    
  19.     public static function obtenerTodos() {
  20.         $personas = array()
  21.         $datos = self::$_persistencia->obtenerTodos();
  22.         foreach($datos as $dato) {
  23.             $persona = new Persona();
  24.             $persona->_id = $datos['id'];
  25.             $persona->_nombre = $datos['nombre'];
  26.             $personas[] = $persona;
  27.         }
  28.         return $personas;
  29.     }
  30.    
  31.     public function guardar() {
  32.         if($this->_id == 0) {
  33.             $this->_id = self::$_persistencia->insertar($this->_nombre);
  34.         } else {
  35.             self::$_persistencia->actualizar($this->_id, $this->_nombre);
  36.         }
  37.     }
  38.    
  39.     public function setNombre($nombre) {
  40.         $this->_nombre = $nombre;
  41.     }
  42.    
  43.     public function getNombre() {
  44.         return $this->_nombre;
  45.     }
  46.    
  47.     public function getId() {
  48.         return $this->_id;
  49.     }
  50. }

Hemos agregado 2 atributos privados, lo que es el id y el nombre, y otro atributo estático que es la instancia de persistencia que es responsable de consultar los datos, el porque es estático este atributo es debido a que se usará tanto en los métodos de instancia como en los métodos de clase y también para evitar que se cree una nueva instancia de persistencia cada ves creemos una persona, veamos el porque:

Tenemos 2 métodos estáticos que son obtener y obtenerTodos que hacen uso de la instancia de persistencia tanto para crear una instancia de una persona de acuerdo al id pasado como parámetro como otro para obtener un arreglo con todas la personas existentes.
Son estáticos porque no es necesario crear una instancia de persona para poder hacer uso de ellos.

Por ejemplo podriamos hacer esto para obtener una persona o el listado completo:

Código php:
Ver original
  1. // Obtenemos la persona con id 1
  2. $persona = Persona::obtener(1);
  3.  
  4. // Obtenemos todo el listado de personas
  5. $personas = Persona::obtenerTodos();

Ahora los métodos de instancia como guardar, se encargaría de mandar la orden ya sea de actualizar o insertar la persona con la ayuda de la persistencia, verificaremos si el id es 0, quiere decir que es nuevo y lo insertaremos, actualizando el atributo id de persona al finalizar la inserción o actualizar si el id está definido.

También tenemos los métodos accesores como setNombre y getNombre para poder modificar y consultar los atributos de persona.

Ahora por ejemplo podriamos crear una instancia de persona de esta forma y guardarla en la base de datos:

Código php:
Ver original
  1. $persona = new Persona();
  2. $persona->setNombre("Juan");
  3. $persona->guardar();

O podriamos obtener alguna persona y modificar su nombre:
Código php:
Ver original
  1. $persona = Persona::obtener(1);
  2. $persona->setNombre("Juan");
  3. $persona->guardar();

No sé si el código tenga errores, no lo pude probar, pero a grandes rasgos me parece una implementación bastante clara.

Espero que te sea de ayuda.

Un saludo y suerte !
__________________
Una contraseña es como la ropa interior. No deberías dejarlas afuera a la vista de otras personas, deberías cambiarla regularmente, y ni se te ocurra prestarla a extraños.
  #9 (permalink)  
Antiguo 20/08/2011, 00:17
 
Fecha de Ingreso: agosto-2011
Mensajes: 3
Antigüedad: 13 años, 4 meses
Puntos: 3
Respuesta: Object Oriented en la cruda realidad

Ronruby, magistral tu respuesta, pero creo que el enfoque no es el correcto. Tu giras todo alrededor del DAO, el DAO es como la base de todo. Creo que no es correcto porque el concepto de usuario o persona no depende de una BD, es un método el usar la BD.

Por otra parte, como he comentado, si no es una BD y son ficheros planos, o simplemente una conexión SOAP tu modelo habría que cambiarlo.

Jahepi, fantástico, esto es para mi lo que mas se aproxima al concepto que entiendo de POO. La Persistencia puede ser cualquier cosa, desde nada porque son objetos de memoria, hasta SOAP, BD, conexión tcp, ...

Me es muy curioso los métodos obtener, y el como devuelven los objetos persona. Creo que es muy elegante.

Voy a probar de implementar un ejemplo real usando el método de ronruby y de jahepi. Gracias a todos, a gustos colores
  #10 (permalink)  
Antiguo 20/08/2011, 06:55
Avatar de masterpuppet
Software Craftsman
 
Fecha de Ingreso: enero-2008
Ubicación: Montevideo, Uruguay
Mensajes: 3.550
Antigüedad: 16 años, 11 meses
Puntos: 845
Respuesta: Object Oriented en la cruda realidad

Que tal drieran,

Creo que no lo estas viendo correctamente, para mi el approach de RonRuby es el adecuado, talves en el ejemplo no se ve claro, y en un mundo ideal el modelo debería estar aislado completamente del mecanismo de persistencia, podría ser algo asi:

model
Código PHP:
Ver original
  1. class User
  2. {
  3.     protected $_name;
  4.     protected $_email;
  5.     protected $_address;
  6.     protected $_phone;
  7.     /*getters && setters*/
  8. }

mapper
Código PHP:
Ver original
  1. class UserMapper
  2. {
  3.     protected $_dao;
  4.  
  5.     public function __construct(UserDao $dao)
  6.     {...}
  7.  
  8.     public function findById($id)
  9.     {
  10.         $record = $this->_dao->find((int)$id);
  11.         $user   = new User();
  12.         $user->setName($record['name'])
  13.              ->setEmail($record['email'])
  14.              ->setAddress($record['address'])
  15.              ->setPhone($record['phone']);
  16.         return $user;
  17.     }
  18.  
  19.     public function save(User $user)
  20.     {
  21.         $data = array(
  22.             'name'    => $user->getName(),
  23.             'email'   => $user->getEmail(),
  24.             'address' => $user->getAddress(),
  25.             'phone'   => $user->getPhone()
  26.         );
  27.         $this->_dao->save($data);
  28.     }
  29. }

dao
Código PHP:
Ver original
  1. interface UserDao
  2. {
  3.     public function find($criteria);
  4.     public function findAll($criteria);
  5.     public function save($data);
  6. }
  7.  
  8. class UserDbDao implements UserDao
  9. {
  10.     protected $_conn;
  11.     public function __construct(PDO $conn)
  12.     {...}
  13. }
  14.  
  15. class UserXMLDao implements UserDao
  16. {
  17.     protected $_file;
  18.     public function __construct($pathToFile)
  19.     {...}
  20. }
  21.  
  22. class UserWebServiceDao implements UserDao
  23. {
  24.     protected $_endpoint;
  25.     public function __construct($endpoint)
  26.     {...}
  27. }

DI Container

Código PHP:
Ver original
  1. class Container
  2. {
  3.     protected $_config;
  4.  
  5.     public function __construct(array $config)
  6.     {...}
  7.  
  8.     public function makeUserMapper()
  9.     {
  10.         $conn   = new PDO($this->_config['pdo.dsn']);
  11.         $dao    = new UserDbDao($conn);
  12.         $mapper = new UserMapper($dao);
  13.         return $mapper;
  14.     }
  15. }

uso:

Código PHP:
Ver original
  1. $container = new Container();
  2. $mapper = $container->makeUserMapper();
  3. $user   = $mapper->findById(1);
  4.  
  5. $user->setName('Zend rulz!');
  6.  
  7. $mapper->save($user);

Pero esto no es mas que un ejemplo muy simple y no muestra la verdadera complejidad, te sugiero que investigues sobre Identity Map, Unit of Work, Virtual Proxy, Lazy initialization, Lazy Loading, Eager Loading y seguro me estoy dejando alguno, lo expuesto aquí no es mas que la punta de la madeja.

Saludos.
__________________
http://es.phptherightway.com/
thats us riders :)
  #11 (permalink)  
Antiguo 20/08/2011, 09:43
Avatar de jahepi
Colaborador
 
Fecha de Ingreso: diciembre-2004
Ubicación: Querétaro
Mensajes: 1.124
Antigüedad: 20 años
Puntos: 43
Respuesta: Object Oriented en la cruda realidad

@masterpuppet
Bastante claro el ejemplo, está perfecta la separación.

@drieran
El ejemplo que te he puesto si quieres manejar otro tipo de medios persistentes como archivos de texto o xml´s como lo ha mostrado masterpuppet sólo hay que agregar una nueva capa de abstracción, tendrías entonces esa capa para acceder a los distintos medios (txt, xml, base de datos) y la parte de base de datos dependería de otra capa de abstracción para conectarte a los diferentes manejadores (Mysql, Firebird, etc...).

Muy buen tema.

Un saludo y suerte !
__________________
Una contraseña es como la ropa interior. No deberías dejarlas afuera a la vista de otras personas, deberías cambiarla regularmente, y ni se te ocurra prestarla a extraños.

Etiquetas: mysql, object, php, realidad, tabla, variables, usuarios
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 3 personas




La zona horaria es GMT -6. Ahora son las 21:30.