Presione → o espacio para avanzar.
Presione ← para retroceder.
Avance y retroceda con la rueda del mouse.
Ctrl + + o - para zoom.
Gestos en pantalla en dispositivos móviles.
|
por Leonardo Tadei <leonardo@tadei.com.ar> http://leonardo.tadei.com.ar Pegasus Tech Supply <leonardot@pegasusnet.com.ar> |
Congreso Internacional de Software Libre 15 de Octubre Biblioteca Nacional, CABA, Argentina |
La técnica por la cual, en un contexto de
Programación Orientada a Objetos (POO),
se almacenan los Objetos del Modelo
en un Gestor de Bases de Datos Relacional (RDBMS).
"Los Objetos Persisten"
La intención de esta arquitectura es
"cuidar" al Modelo.
usar una Base de Datos Orientada a Objetos (ODBMS, object
database management system).
Requieren binding con el lenguaje.
No hay disponibles para PHP
La idea subyacente a la arquitectura MVC
es preservar el Modelo.
Existen implementaciones de ORM que pierden de vista la preservación del modelo proponiendo
mecanismos aparentemente inocentes, pero que implican o violar el paradigma de la POO o
introducir cambios en el Modelo que no tienen que ver con las reglas del negocio.
<?php
class Cliente extends MyORM {...}
$c = new Cliente();
// código que modifica el valor de los atributos
$c->save();
?>
<?php
class Cliente {
public $nombre = '';
public $limiteCredito = 0.00;
...
}
?>
Se violan principios fundamentales de la POO:
<?php
class Cliente {
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
...
}
?>
<?php
$c1 = Cliente::findById(34);
...
$c2 = Cliente::findByName('Perez');
?>
Dada la clase:
<?php
class Auto {
private $patente; // la patente del automóvil
private $carga; // peso en Kg
function __construct($p = '', $c = 0) {
$this->setPatente($p);
$this->setCarga($c);
}
function setPatente($v) { $this->patente= $v; }
function getPatente() { return $this->patente; }
function setCarga($v) { $this->carga = $v; }
function getCarga() { return $this->carga; }
function calcularConsumo() {
return 8 * (1 + $this->getCarga() / 1000;
}
}
?>
Persistencia no Invasiva del Objeto
<?php
$p = new Persistent(); // instanciamos al ORM
$a1 = new Auto('GNU-007', 280); // creamos una instancia de Auto
print('El consumo es: '. $a1->calcularConsumo()); // mostramos el consumo
$p->save($a1); // el mapeador persiste al objeto
?>
Hidratación del Objeto
<?php
$p = new Persistent(); // instanciamos al ORM
$a1 = $p->retrieve('Auto','GNU-007'); // hidratamos la instancia
print('El consumo es: '. $a1->calcularConsumo()); // mostramos el consumo
$a->setCarga(500);
print('El consumo cambió: '. $a1->calcularConsumo()); // mostramos el consumo
$p->save($a1); // el mapeador persiste al objeto con su estado actual
?>
El ORM funciona como un repositorio virtual de Objetos. Intenta dar la sensación de que, una vez
creado un objeto, este existe, y por tanto no debe ser vuelto a crear para ser usado nuevamente.
Eliminación permanente del Objeto
<?php
$p = new Persistent(); // instanciamos al ORM
$a1 = $p->retrieve('GNU-007'); // hidratamos la instancia
print('El consumo es: '. $a1->calcularConsumo()); // mostramos el consumo
$p->delete($a1); // el Objeto es removido del repositorio
var_dump($a1); // devuelve NULL: el Objeto ya no existe
?>
Para persistir el Objeto, como para actualizarlo o eliminarlo, siempre se
trabaja con una instancia del mismo.
<?php
class CollectionAuto implements IteratorAggregate {
private $items = array(); // la implementación queda oculta.
// Métodos
public function getIterator() {
return new ArrayIterator($this->items);
}
// el método add() solo acepta instancias de Auto
public function add(Auto $obj) {
$this->items[] = $obj;
}
}
?>
Nuestra propuesta de mapeo para trabajar con Colecciones requiere la
implementación de esta interfaz.
<?php
$p = new Persistent(); // instanciamos al ORM
$c = new CollectionAuto(); // instanciamos la colección
$total = $p->retrieveCollection('Auto', $c); // hidrata los Autos y los agrega a $c
print("Existen $total instancias de Auto en el repositorio.");
foreach ($c as $auto) { // recorre los autos hidratados
var_dump($auto);
}
?>
<?php
class Provincia {
private $nom;
public function __construct ($nom='') {
$this->setNom($nom);
}
public function setNom ($v) { $this->nom = $v; }
public function getNom() { return $this->nom; }
}
class Localidad {
private $nom;
private $provincia; // Instancia de Provincia
public function __construct ($nom='', Provincia $provincia = NULL) {
$this->setNom($nom);
$this->setProvincia($provincia);
}
public function setNom ($v) { $this->nom = $v; }
public function getNom() { return $this->nom; }
public function setProvincia ($v) { $this->provincia = $v; }
public function getProvincia() { return $this->provincia; }
}
?>
<Persistent>
<Provincia>
<Table><Name>Provincias</Name></Table>
<ObjectId>nom</ObjectId>
</Provincia>
<Localidad>
<Table><Name>Localidades</Name></Table>
<ObjectId>nom</ObjectId>
<Attributes>
<provincia>
<field>id_pro</field>
<relation type="agregation">1-1</relation>
<reference>Provincia</reference>
</provincia>
</Attributes>
</Localidad>
</Persistent>
Descarga del paper (PDF)
Descarga del paper http://pegasusnet.com.ar/difusion/2012-10-ORM (HTML)
Descarga directa del ORM
Descarga del ORM (internet)
http://pegasusnet.com.ar/difusion/2012-10-ORM/phporm.tar.gz
|
por Leonardo Tadei <leonardo@tadei.com.ar> http://leonardo.tadei.com.ar Pegasus Tech Supply <leonardot@pegasusnet.com.ar> Creative Commons Attribution 2.5 Argentina License http://creativecommons.org/licenses/by/2.5/ar/ |
|