Ver Mensaje Individual
  #11 (permalink)  
Antiguo 02/06/2006, 01:43
Avatar de Hereje
Hereje
 
Fecha de Ingreso: junio-2002
Ubicación: Córdoba, Argentina
Mensajes: 439
Antigüedad: 21 años, 11 meses
Puntos: 2
Hola nuevamente:

Viendo que con Iterator en PHP5 las cosas estan más puras (no sé que significa esto, pero así dice Casuis ) y simples, me tomé el atrevimiento de hacer una implementación casera de este patrón en PHP4 que quiero compartir para saber si la misma está interpretada correctamente.

Debido a las limitaciones de la versión que utilizo, he tenido que hacer la siguiente clase:

Código PHP:
<?php

class Iterador {

    var 
$_matriz;
    var 
$_puntero;

    function 
iterador(& $matriz) {
        if(!
is_array($matriz))
            return 
false;
            
        
$this->_matriz =& $matriz;
        
$this->reajustar();
        
        return 
true;
    }

    function & 
iterar($devolver_al_terminar false) {
        
$this->_puntero++;
        if(isset(
$this->_matriz[$this->_puntero]))
            return 
$this->_matriz[$this->_puntero];
        else
            
$this->reajustar();
        
        return 
$devolver_al_terminar;
    }
    
    function 
reajustar() {
        
$this->_puntero = -1;
    }
    
}
?>
Está en su mínima expresión, se le pueden agregar un par de métodos más en caso de ser necesario.

Siguiendo el ejemplo de Casuis de Curso-Alumno:

Clase Alumno:
Código PHP:
<?php

class Alumno {

    var 
$_id;
    var 
$_nombre;
    
    function 
alumno($id$nombre) {
        
$this->_id $id;
        
$this->_nombre $nombre;
    }
    
    function 
getId() {
        return 
$this->_id;
    }
    
    function 
getNombre() {
        return 
$this->_nombre;
    }
    
    function 
setNombre($valor) {
        
$this->_nombre $valor;
    }

}
?>
No sufre modificaciones con respecto a la anterior, pero la he achicado un poquito para hacer las pruebas.

Clase Curso:
Código PHP:
<?php

class Curso {

    var 
$_nombre;
    var 
$_alumnos;
    
    var 
$_iterador_alumno;
    
    function 
curso($nombre) {
        
$this->_nombre $nombre;
    }
    
    function 
getNombre() {
        return 
$this->_nombre;
    }

    function 
addAlumno(& $alumno) {
        
$this->_alumnos[] =& $alumno;
    }

    function & 
getAlumnos() {
        if(empty(
$this->_iterador_alumno))
            
$this->_iterador_alumno =& new Iterador($this->_alumnos);

        return 
$this->_iterador_alumno->iterar();
    }
        
}
?>
Las modificaciones son:
  • El "&" al argumento del método addAlumno, para mantener la refencia y
  • el método getAlumnos el cual hace uso de una instancia de Iterador en la propiedad _iterador_alumno.

Quedaría:
Código PHP:
<?php

$alumno_1 
=& new Alumno(1'Sergio');
$alumno_2 =& new Alumno(2'Cesar');

$curso_php =& new Curso('PHP');
$curso_php->addAlumno($alumno_1);
$curso_php->addAlumno($alumno_2);

while(
$alumno =& $curso_php->getAlumnos())
    echo 
$alumno->getNombre();

?>
Las referencias están perfectas, pues hacer la prueba de cambiar los nombres en el bucle y luego corroborar en $alumno_1 y $alumno_2.

Algo que me parece que está mal es que no puedo personalizar la iteración de una clase específica, ya que todo el control es dado a la clase Iterador. ¿Esto esta mal, no? ¿Deberia hacer una implementación interna de Iterator en cada clase que necesite esta funcionalidad?

Lecturas de inspiración :
Muchas gracias! Saludos.
__________________
Sergio