Ver Mensaje Individual
  #1 (permalink)  
Antiguo 30/12/2008, 03:39
Sanva
 
Fecha de Ingreso: diciembre-2005
Ubicación: Redondela (Galicia)
Mensajes: 368
Antigüedad: 18 años, 4 meses
Puntos: 1
Duda: Como inicializar propiedades públicas (filtradas) de un objeto

Hola a todos.

Últimamente me estoy poniendo en serio con POO en PHP5 —hasta hace poco casi todo el código en mis aplicaciones era PHP5 al estilo de PHP4, y quiero que eso cambie—, y hoy me ha surgido una duda: ¿Cual es la forma óptima de inicializar una propiedad pública, pero filtrada, de un objeto?

Es decir, yo tengo este código:

Código PHP:
class Prueba{
    
    private 
$a//Debe ser una cadena, por ejemplo.
    
    
public function __construct($arg 'Default'){
        
        
$this -> $arg;
        
    }
    
    public function 
__set($var$value){
        
        switch(
$var){
            
            case 
'a':
            
                if (
is_string($value)) $this -> $value;
                else throw new 
MyException('foo');
            
            default:
                
                throw new 
MyException02('foo02');
            
        }
        
    }
    

Pero no funciona, ya que el $this -> a = $arg; del constructor define la propiedad directamente, sin pasar por el __set, pues no importa que sea privada ya que es el propio objeto el que hace la llamada.

Otra opción:

Código PHP:
class Prueba{
    
    private 
$a//Debe ser una cadena, por ejemplo.
    
    
public function __construct($arg 'Default'){
        
        
$this -> __set('a'$arg);
        
    }
    
    public function 
__set($var$value){
        
        switch(
$var){
            
            case 
'a':
            
                if (
is_string($value)) $this -> $value;
                else throw new 
MyException('foo');
            
            default:
                
                throw new 
MyException02('foo02');
            
        }
        
    }
    

Esta no me acaba de gustar, pues me parece que empeora un poco el rendimiento de la clase, ya que introduce un salto en el código (una llamada a un método) por cada propiedad a inicializar desde el constructor... ¿a vosotros qué os parece?

Otra:

Código PHP:
class Prueba{
    
    private 
$a//Debe ser una cadena, por ejemplo.
    
    
public function __construct($arg 'Default'){
        
        
$this -> setA($arg);
        
    }
    
    public function 
__set($var$value){
        
        switch(
$var){
            
            case 
'a':
            
                
$this -> setA($value);
            
            default:
                
                throw new 
MyException02('foo02');
            
        }
        
    }
    
    private function 
setA{
        
        if (
is_string($value)) $this -> $value;
        else throw new 
MyException('foo');
        
    }
    

Esta me gusta menos, ya que hace que el código crezca muchísimo (¿¿un método privado por cada propiedad??). Además, creo que es aún menos eficiente ya que introduce un nuevo salto en el código: Mantiene el del constructor, y añade un salto si el programador decide cambiar la propiedad (ya que incorpora una función al __set, en lugar de estar en él el código).

Y lo último que se me ocurre es duplicar el código en el constructor:

Código PHP:
class Prueba{
    
    private 
$a//Debe ser una cadena, por ejemplo.
    
    
public function __construct($arg 'Default'){
        
        if (
is_string($arg)) $this -> $arg;
        else throw new 
MyException('foo');
        
    }
    
    public function 
__set($var$value){
        
        switch(
$var){
            
            case 
'a':
            
                if (
is_string($value)) $this -> $value;
                else throw new 
MyException('foo');
            
            default:
                
                throw new 
MyException02('foo02');
            
        }
        
    }
    

Lo cual creo que es lo más óptimo desde el punto de vista del rendimiento... pero me gustaría saber si existe una diferencia práctica entre este y el primero, ya que este no me gusta nada pues lo de duplicar código para el mantenimiento del programa es fatídico.

¿Cual es vuestra opinión acerca de este problema? ¿O es simplemente que tengo un error en mi planteamiento sobre objetos y clases?

Gracias por vuestro tiempo.