setters orientado objetos métodos mvc metodo getters crear php oop getter-setter

php - orientado - ¿Debo o no debo usar los métodos getter y setter?



métodos getters y setters php (7)

Bueno, esto realmente me está molestando y estoy empezando a pensar que todo se reduce a una elección personal en lugar de a una forma particular de ser más eficiente o escribir mejor el código: ¿Debería o no debería usar métodos de obtención / establecimiento en un proyecto PHP? ? Las respuestas que he leído hasta ahora son bastante contradictorias y no están del todo adaptadas a PHP, que no es un lenguaje compilado. Por ejemplo, tome esta pregunta sobre el desbordamiento de pila (" ¿Por qué usar getters y setters ?"). Hay una serie de buenas razones por las que debo usarlas dentro de mi código, sin embargo, todos los comentarios de niños mencionan cómo los Accesores son malos y deben evitarse, intercalados entre algunos comentarios más inquietantes que mencionan que deben evitarse por completo porque "Mucks tu código".

Lo único que recibo son respuestas conflictivas, ninguna de las cuales es relevante para un entorno PHP interpretado. ¿Alguien puede arrojar algo de luz sobre por qué / por qué no deberían usarse dentro de PHP, y su razonamiento detrás de esa decisión? ¿Realmente importa si podemos definir simplemente una propiedad como privada o protegida y, de todos modos:

La oferta de captadores y definidores de encapsulación es ridículamente delgada

... citado de "sbi" (¿Por qué usar getters y setters?)

Personalmente, todavía no veo cómo:

Class Foo { public $bar; function setBarType($val) { $this->bar = $val; } } $fee = new Foo(); $fee->setBarType(42);

es superior a esto:

Class Foo { public $bar; } $fee = new Foo(); $fee->bar = 42;


El uso de IMO con captadores y definidores es una buena práctica y también aumenta la legibilidad del código. Además de verificar el valor mientras se configura, hay otro ejemplo, considere si llama u getMoviesList() . Ahora este método de obtención se puede implementar de cualquier manera, puede obtener la lista de películas de la base de datos local, obtenerla del servicio web en línea, etc. Así que el código que toma la decisión puede estar dentro de esta función. Desde donde lo llames, no te importa la ubicación y cómo se obtiene. U acaba de obtener la lista de películas .


La elección depende de usted. Otras características importantes de PHP 5 a tener en cuenta son los que obtienen / configuran la magia:

http://www.php.net/manual/en/language.oop5.overloading.php#object.set http://www.php.net/manual/en/language.oop5.overloading.php#object.get

La magia de esto es que puedes hacer algo como lo siguiente y decidir dónde obtener / establecer variables sin tener que declararlas de antemano:

Class Foo { private $data = array(); function __set($name,$val) { $this->$data[$name] = $val; } function __get($name,$val) { if (array_key_exists($name, $this->data)) { return $this->data[$name]; } }

Voila, algo como esto ahora pasa automágicamente:

$ fee = new Foo (); $ fee-> bar = 42;


La publicación de blog a la que te vinculas comienza con una oración crucial (énfasis agregado):

Cada captador y definidor en su código representa una falla al encapsular y crea un acoplamiento innecesario.

La encapsulación es la idea más importante de la programación orientada a objetos. Básicamente, se reduce a ocultar la complejidad envolviéndola cuidadosamente dentro de las clases. En un mundo ideal, cuando utiliza una clase, no debería tener que saber nada sobre su funcionamiento interno o su estado. Algunas personas (como este autor del blog) argumentarán que tener captadores y definidores ya es demasiada información sobre el interior de la clase. En su opinión, una clase solo debería tener métodos que nos permitan decirle a un objeto que haga algo , sin importar cómo lo hace o en qué estado se encuentra. Usar un setter no es "decirle al objeto que haga algo", es Mucking con el estado del objeto desde el exterior.

En lugar de hacer esto:

$a = myObject(); // Querying object state, making a decision outside the object, and changing its state if ($a->getWarbleFizz() < 42) { $a->setYourWarbleFizzTo(42); } // Gee, I hope I made the right decision... $a->nowDoSomethingUseful();

Deberías escribir código como este:

$a = myObject(42); $a->doStuff();

O esto :

$a = myObject(); $a->doStuff(42);

Lectura relacionada: Dile, no preguntes .


Porque si la implementación de cómo se establece el valor cambia (a un db), no tiene que cambiar los llamadores. Otro ejemplo es que es posible que deba verificar el valor antes de establecerlo.

Tener un método le permite interceptar la configuración / obtención de esa variable, hacerlo cuando no parece que lo necesite, hace que su código sea más fácil de cambiar.

Captadores de propiedades

Los lenguajes como C # y las versiones recientes de JavaScript le permiten interceptar la lectura y escritura de propiedades, por lo que solo puede usar las propiedades en los idiomas que lo admiten.

Observadores de objetos

Algunos idiomas le permiten interceptar la lectura / configuración de todos los Object.watch de JavaScript , o propiedades inaccesibles con el __get de PHP . Esto le permite implementar getters y setters pero obtiene un impacto en el rendimiento debido a la sobrecarga que crean para cada acceso de propiedad. Esta respuesta habla de otros problemas con los que consiguen y los que establecen. Práctica recomendada: métodos mágicos de PHP __set y __get

Getters y Setters están bien, pero ...

Hacerlo solo es bueno, pero es casi tan malo como las propiedades públicas. Si alguien puede cambiar el estado de su objeto (especialmente con múltiples propiedades), no estará bien encapsulado. http://cspray.github.io/2012/05/13/stop-calling-them-getters-setters.html


Si no utiliza captadores y definidores en un lenguaje como PHP, que no es de tipo seguro, ¿cómo se asegurará de que el tipo de propiedad del objeto sea correcto?

Puede que me esté perdiendo el punto por completo, pero si necesita acceder a una propiedad desde fuera del objeto, creo que sigue siendo la mejor opción para usar los accesores ...

Además, como menciona Juon Mendes: algunos idiomas le ofrecen interceptar cuando se están abordando las propiedades en sí. Esto también puede estar llegando a PHP

Incluso podrías tener un setter público y un getter protegido:

class TimePeriod { protected $Seconds = 3600; public $Hours { get { return $this->Seconds / 3600; } set { $this->Seconds = $value * 3600; } } // This property is read only as there is no setter public $Minutes { get { return $this->Seconds / 60; } } /* public getter, protected setter */ public $Milliseconds { get { return $this->Seconds * 1000; } protected set { $this->Seconds = $value / 1000; } } }


Un principio OOP es la encapsulación. Una clase es responsable de todas las variables que están contenidas dentro de esta clase.

Al establecer una variable pública, estás rompiendo ese principio.

Al crear un elemento de acceso (definidor), estás rompiendo indirectamente ese principio al dar la posibilidad de que ese valor se cambie fuera de la clase.

La ventaja de un captador es que el método de llamada no necesita preocuparse por cómo se recuperan los datos. Solo se sabe que obtendrá los datos esperados y eso es todo. Aquí se respeta el principio de encapsulación.

La ventaja de un definidor es que la clase tiene la oportunidad de verificar el nuevo valor antes de aplicarlo. En un mundo perfecto, no hay necesidad de accesores porque una clase puede administrar completamente todas sus variables. En el mundo real, a veces es necesario establecer un valor o obtenerlo desde el exterior.

La mejor manera de acercarse al mundo perfecto es limitar los accesores solo a las pocas variables que deben modificarse. Y verifique los valores establecidos si es posible.

Acerca de su ejemplo, la segunda solución es mejor porque guarda un nivel en la pila php. Su accessor es inútil porque su variable es pública de todos modos (por lo tanto, no hay encapsulación) y no realiza ninguna verificación adicional. Pero cuando sea posible, DEBE usar el descriptor de acceso para verificar los datos. Si los datos no son necesarios en ninguna otra parte de su aplicación, entonces, no haga ningún acceso.


Una gran ventaja de usar un captador y configurador es que, siempre que necesite realizar cambios, solo tiene que modificarlo.

Trataré de explicar con un ejemplo:

protected $date; public function getDate(){ return $this->date; } public function setDate($date){ $this->date = $date; }

Imagina que hay una razón por la cual la fecha siempre debe incrementarse con un día. Tendrá que buscar en todo el proyecto donde accedió a su miembro de la clase.

Pero mediante el uso de getters y setters puede cambiar el código a:

protected $date; public function getDate(){ return $this->date; } public function setDate($date){ $date = new DateTime($date); $date->modify(''+1 day''); $this->date = $date; }