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

Colección de objetos de diferentes clases

Estas en el tema de Colección de objetos de diferentes clases en el foro de Frameworks y PHP orientado a objetos en Foros del Web. Hola a todos. Una consulta: Quisiera saber como manejo una colección de objetos de clases diferentes, heredados de una super clase abstracta, si es que ...
  #1 (permalink)  
Antiguo 04/02/2010, 11:40
 
Fecha de Ingreso: enero-2005
Ubicación: Barcelona (España)
Mensajes: 134
Antigüedad: 19 años, 3 meses
Puntos: 0
Colección de objetos de diferentes clases

Hola a todos. Una consulta:

Quisiera saber como manejo una colección de objetos de clases diferentes, heredados de una super clase abstracta, si es que es posible. Cuando la clase no es abstracta, no tengo problemas. Por ejemplo, con las típicas clases de Producto y ConjuntoProductos, lo hago así:
Código PHP:
class Producto {
  ...
  public static function 
load($id$conn) {
    ...
    return 
$producto;
  }
}

class 
ConjuntoProductos {
  ...
  public function 
getTodosLosProductos($conn) {
    
$productos = array();
    
$sql "SELECT * FROM producto ORDER BY id";

    if (
$res $conn->query($sql)) {
      while (
$row $res->fetch_assoc())
      {
         
$productos[] = Producto::load($row['id'], $conn);    
      } 
      return 
$productos;
    } else {
      throw new 
SQLException("Error en la base de datos");
    }
  }
  ...

Pero ahora quiero hacer una variación. Tengo una clase abstracta Producto, de la cual heredan otras, como ProductoDeTipoA y ProductoDeTipoB. Me gustaría tener una colección de productos, de todos, en la que habrá mezclados productos de un tipo y de otro. Tengo:

Código PHP:
abstract class Producto {
  ...
}
class 
ProductoDeTipoA extends Producto {
  ...
  public static function 
load($id$conn) {
    ...
    return 
$producto;
  }
}
class 
ProductoDeTipoB extends Producto {
  ...
  public static function 
load($id$conn) {
    ...
    return 
$producto;
  }

Me gustaría saber como tendría que implementar el método ConjuntoProductos->getTodosLosProductos(), teniendo en cuenta que puede haber productos de los dos tipos, y a priori no sé de que tipo son

Código PHP:
class ConjuntoProductos {
  ...
  public function 
getTodosLosProductos($conn) {
    
$productos = array();
    
$sql "SELECT * FROM producto ORDER BY id";

    if (
$res $conn->query($sql)) {
      while (
$row $res->fetch_assoc())
      {
         
//Aquí, al hacer el load no se a que clase tengo que llamar (TipoA?, TipoB?)
         
$productos[] = Producto::load($row['id'], $conn);    
      } 
      return 
$productos;
    } else {
      throw new 
SQLException("Error en la base de datos");
    }
  }
  ...

Gracias, y disculpad por el peñazo...
  #2 (permalink)  
Antiguo 04/02/2010, 12:15
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Colección de objetos de diferentes clases

Para eso es mejor que tengas en tu base de datos un campo "tipo", y que uses el patrón Factory para cargar los productos así tienes un ProductFactory que se encarga de cargar y crear Productos y así no importa del tipo que sean.

Saludos.
  #3 (permalink)  
Antiguo 05/02/2010, 05:30
 
Fecha de Ingreso: enero-2005
Ubicación: Barcelona (España)
Mensajes: 134
Antigüedad: 19 años, 3 meses
Puntos: 0
Respuesta: Colección de objetos de diferentes clases

Ok, gracias GatorV. Echaré un vistazo al patrón Factory ese que me comentas. Soy bastante principiante y aún tengo mucho que estudiar antes de meterme en temas más avanzados, como los patrones.

Yo estaba abordando este problema como un caso de polimorfismo. ¿No sería éste el caso? Se trata de usar un mismo método desde clases diferentes. ¿Estoy muy equivocado?
  #4 (permalink)  
Antiguo 05/02/2010, 10:12
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Colección de objetos de diferentes clases

Es que sí implica un poco pero para solucionarlo es mucho más sencillo si lo haces usando Factory, ya que es un patrón muy sencillo mira te dejo un ejemplo:
Código PHP:
Ver original
  1. class Producto {
  2.     public static function factory($sProductType, $aData)
  3.     {
  4.         $sProductType = ucfirst($sProductType);
  5.         $sProduct = "Product{$sProductType}";
  6.         $sProductFileClass = $sProduct.".php";
  7.        
  8.         if (file_exists("/path/a/las/clases/{$sProductFileClass}")) {
  9.             include "/path/a/las/clases/{$sProductFileClass}";
  10.             $Product = new $sProduct($aData);
  11.         } else {
  12.             throw new Exception("Error, el tipo de producto: {$sProductType} no existe");
  13.         }
  14.        
  15.         return $Product;
  16.     }
  17. }

Así si tienes tus archivos ProductoTipoA.php, ProductoTipoB.php y tus clases ProductoTipoA y ProductoTipoB, puedes hacer algo así:
Código PHP:
Ver original
  1. class ConjuntoProductos {
  2.   ...
  3.   public function getTodosLosProductos($conn) {
  4.     $productos = array();
  5.     $sql = "SELECT * FROM producto ORDER BY id";
  6.  
  7.     if ($res = $conn->query($sql)) {
  8.       while ($row = $res->fetch_assoc())
  9.       {
  10.          $productos[] = Producto::factory($row['type'], $row);    
  11.       }
  12.       return $productos;
  13.     } else {
  14.       throw new SQLException("Error en la base de datos");
  15.     }
  16.   }
  17.   ...
  18. }

Saludos.
  #5 (permalink)  
Antiguo 08/02/2010, 05:18
 
Fecha de Ingreso: enero-2005
Ubicación: Barcelona (España)
Mensajes: 134
Antigüedad: 19 años, 3 meses
Puntos: 0
Respuesta: Colección de objetos de diferentes clases

Ok, gracias GatorV. Me ha sido de mucha utilidad

Etiquetas: clases, diferentes, objetos
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




La zona horaria es GMT -6. Ahora son las 10:51.