2011-07-17 58 views
6

viniendo de Java, solo tengo algunas visitas de vacaciones a PHP. Al ver los métodos de obtención y configuración de magia, mi barriga (influenciada por Java) comienza a doler: parece que estás accediendo directamente a las propiedades (aunque, por supuesto, en realidad estás usando __get y __set).¿Existen ventajas al usar __get/__ set en lugar de los métodos getter/setter tradicionales a excepción de menos código?

Entonces, excepto por el código menor que tiene que escribir, ¿hay alguna ventaja de usar métodos get y magic setter en lugar de los métodos tradicionales getX()/setX()? ¿Debo comenzar a usarlos cuando codifique PHP?

¡Gracias y el mejor!

+2

Hay momentos en que lo he encontrado conveniente, pero dejaré que otros contesten por otros motivos. Sin embargo, señalaré que usar __get/__ set es mucho más lento ... aproximadamente 10 veces más. No sé por qué y no lo he comparado, pero está documentado en el sitio de PHP. – Brad

+2

Consulte http://programmers.stackexchange.com/questions/62383/what-is-the-point-of-properties para obtener un "¿Por qué propiedades más general?" pregunta. – delnan

Respuesta

1

__get__ y __set__ son totalmente dinámicos. Entonces, por ejemplo, puede iniciar una solicitud de base de datos si se llaman para habilitar la carga diferida. Por supuesto, también podrías hacer esto con getters y setters, pero tendrías que hacer esto cada vez. También puede hacer algo como AOP porque cada llamada de propiedad pasa por un único método. Así que, en general, __get__/__set__ ofrecen una mayor flexibilidad frente al tiempo que tardan en procesarse. Puedes hacer cosas realmente avanzadas/geniales con él.

1

Las ventajas son que cuando se está refactorizando, las asignaciones/lecturas directas se pueden manejar sin la necesidad de cambiar inmediatamente la base de código completa, el código puede ser algo más corto y las personas pueden crear cadenas de una manera más fácil (por ejemplo : $title="<title>{$obj->title}</title>"; vs $title='<title>'.$obj->getTitle().'</title>';

Sin embargo, __get & __set métodos pueden llegar a ser grande y difícil de manejar con bastante rapidez, y al codificar correctamente & explícitamente, es en mi opinión, mejor usar set/getX() métodos explícitos para realizar funciones claras para los llamados, y. el aumento menor de la verbosidad del código está justificado en lo que a mí respecta, ya que uno puede ver fácilmente lo que realmente llama una función y lo que no. Una posible excepción podría ser cuando estás construyendo un decorador para otra clase/objeto, pero eso es todo.

1

hay poca diferencia entre los métodos getter y setter y los métodos __set() y __get()! estos son métodos mágicos! __set() usar cuando quiera asignar un estado indefinido a un objeto y entonces __get() también se usa para obtener el valor de estado indefinido! setter y getter se utilizan para asignar o recuperar el valor de los estados definidos

2

El único beneficio de __get() es la posibilidad de menos código, pero incluso así no es necesariamente el caso. Por ejemplo, si tiene un conjunto de 10 miembros privados y desea que el captador revele 5, debe escribir __get() para que, si se llama a uno de los miembros visibles a psuedo, lo envíe. De lo contrario, o bien emite un error (que de otra manera llegará de forma natural y sin __get() o devolver un valor como null que en realidad no puede ser de ayuda.

debo excoriate cualquiera que sugiere el uso de captadores y definidores en general a todos. Por lo general, indica un problema con la arquitectura explicar la diferencia conceptual entre las dos siguientes bloques de código, por ejemplo:.

class _ { 
    public $_; 
} 

vs

class _ { 
    private $_; 
    public function get_() { 
     return $this->_; 
    } 
} 

no hay una difere nce.

Sin embargo, como muchos señalarán, la ventaja de tener un getter es que esto le permite modificar el valor de retorno de alguna manera transparente para que sea útil para el destinatario. Sin embargo, volvemos a los problemas de arquitectura. Nunca deberías tener que exponer el contenido de una clase por ningún motivo. En cambio, debe decirle a la clase que realice una acción (que puede variar según su estado). El uso de getters generalmente permite consultar el estado de la clase y realizar una acción externamente en función del estado visualizado.

que tienen esencialmente los mismos argumentos contra __set() y definidores, pero no es una cosa agradable que le permite hacer __set():

class _ { 
    private $_ = array(); 
    public function __set($key, $val) { 
     $this->_[$key] = $val; 
    } 
} 

Esto le permite escribir el $_obj->key = 'val' muy agradable. Tenga en cuenta que no hay mucha diferencia con esto y agrega otro método como add() que toma la clave y el valor y hace lo mismo, prefiero la notación del generador de objetos.

0

excepto por el código menor que tiene que escribir, ¿hay alguna ventaja en utilizar métodos magic getter y setter> en lugar de los métodos tradicionales getX()/setX()? ¿Debo comenzar a usarlos cuando codifique PHP?

Dado que hay menos código para escribir, ya es una buena razón para comenzar a usarlos.
la otra razón es que se puede añadir un comportamiento común a toda su captador/definidor

function __set() { 
    //> Do some code in common between all setter 

    //> set your var here 
} 
0

Al escribir getX()/setX() para cada atributo, en la práctica, tendrá como mínimo, 7 líneas de código. Esto supone que su llave de método de apertura está en la misma línea que la definición y que solo pone una sola línea de código en el método, entonces tiene su llave de cierre en su propia línea.

Para un objeto no trivial, multiplique eso por 6 (YMMV). Eso es 42 líneas solo para acceso de atributo/mutación. Eso no incluye incluyendo entrada de validación o normalización. Para una alternativa, consulte: https://github.com/metaphp/attributes

0

Hay gastos generales en la programación dinámica (por ejemplo, utilizando métodos mágicos). Un punto de referencia antigua: Benchmarking magic

Como PHP es un dinámico (y no un completamente empresa) el lenguaje, la reducción de líneas de código y faltan algunos nanosegundos parece buena idea en muchos casos (para la depuración, la escalabilidad, reduciendo errores y etc.)

Cuestiones relacionadas