Ver Mensaje Individual
  #7 (permalink)  
Antiguo 19/08/2011, 10:32
Avatar de Ronruby
Ronruby
 
Fecha de Ingreso: julio-2008
Ubicación: 18°30'N, 69°59'W
Mensajes: 4.879
Antigüedad: 16 años, 4 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