¿Cuál es la forma "purista" o "correcta" de acceder a las propiedades de un objeto desde dentro de un método de objeto que no es un método getter / setter?
Sé que desde fuera del objeto deberías usar un getter / setter, pero desde dentro harías:
Java:
String property = this.property;
PHP:
$property = $this->property;
o harías:
Java:
String property = this.getProperty();
PHP:
$property = $this->getProperty();
Perdóname si mi Java está un poco mal, ha pasado un año desde que programé en Java ...
EDITAR:
Parece que la gente está asumiendo que estoy hablando solo de variables / propiedades privadas o protegidas. Cuando aprendí OO, me enseñaron a usar getters / setters para cada propiedad, incluso si era pública (y en realidad me dijeron que nunca hiciera pública ninguna variable / propiedad). Por lo tanto, puedo estar partiendo de una suposición falsa desde el principio. Parece que las personas que responden a esta pregunta tal vez estén diciendo que debería tener propiedades públicas y que esas no necesitan captadores y establecedores, lo que va en contra de lo que me enseñaron y de lo que estaba hablando, aunque tal vez eso deba discutirse como bien. Sin embargo, probablemente sea un buen tema para una pregunta diferente ...
Personalmente, siento que es importante mantener la coherencia. Si tiene getters y setters, utilícelos. La única vez que accedería a un campo directamente es cuando el descriptor de acceso tiene mucha sobrecarga. Puede parecer que estás inflando tu código innecesariamente, pero ciertamente puede ahorrarte muchos dolores de cabeza en el futuro. El ejemplo clásico:
Más adelante, es posible que desee cambiar la forma en que funciona ese campo. Tal vez debería calcularse sobre la marcha o tal vez le gustaría usar un tipo diferente para la tienda de respaldo. Si accede a las propiedades directamente, un cambio como ese puede romper una gran cantidad de código de una sola vez.
fuente
Estoy bastante sorprendido de lo unánime que es el sentimiento de que los
getters
armadores están bien y bien. Sugiero el artículo incendiario de Allen Holub " Getters And Setters Are Evil ". Por supuesto, el título es por valor de impacto, pero el autor hace puntos válidos.Esencialmente, si tiene
getters
ysetters
para todos y cada uno de los campos privados, está haciendo que esos campos sean tan buenos como públicos. Sería muy difícil cambiar el tipo de campo privado sin efectos dominó en cada clase que lo llamegetter
.Además, desde un punto de vista estrictamente orientado a objetos, los objetos deben responder a mensajes (métodos) que correspondan a su (con suerte) responsabilidad única. La gran mayoría de
getters
ysetters
no tienen sentido para sus objetos constituyentes;Pen.dispenseInkOnto(Surface)
tiene más sentido para mí quePen.getColor()
.Los captadores y definidores también alientan a los usuarios de la clase a pedir al objeto algunos datos, realizar un cálculo y luego establecer algún otro valor en el objeto, mejor conocido como programación procedimental. Sería mejor que le dijera simplemente al objeto que haga lo que iba a hacer en primer lugar; también conocido como el modismo Information Expert .
Los getters y setters, sin embargo, son males necesarios en el límite de las capas: UI, persistencia, etc. El acceso restringido a los elementos internos de una clase, como la palabra clave friend de C ++, el acceso protegido al paquete de Java, el acceso interno de .NET y el patrón de clase Friend pueden ayudarlo a reducir la visibilidad de
getters
y los establecedores solo a aquellos que los necesitan.fuente
Depende de cómo se utilice la propiedad. Por ejemplo, supongamos que tiene un objeto de estudiante que tiene una propiedad de nombre. Puede usar su método Get para extraer el nombre de la base de datos, si aún no lo ha recuperado. De esta forma, reduce las llamadas innecesarias a la base de datos.
Ahora digamos que tiene un contador de enteros privado en su objeto que cuenta el número de veces que se ha llamado al nombre. Es posible que desee no utilizar el método Get desde el interior del objeto porque produciría un recuento no válido.
fuente
PHP ofrece una gran variedad de formas de manejar esto, incluidos los métodos mágicos
__get
y__set
, pero prefiero captadores y definidores explícitos. Este es el por qué:fuente
Quizás ;)
Otro enfoque sería utilizar un método privado / protegido para realizar la obtención (almacenamiento en caché / db / etc), y una envoltura pública que incremente el recuento:
PHP:
y luego desde dentro del propio objeto:
PHP:
De esta manera, aún puede usar ese primer argumento para otra cosa (como enviar una bandera para indicar si se usarán o no datos almacenados en caché aquí).
fuente
Debo estar perdiendo el punto aquí, ¿por qué usarías un captador dentro de un objeto para acceder a una propiedad de ese objeto?
Llevando esto a su conclusión, el captador debería llamar a un captador, que debería llamar a un captador.
Entonces, diría que dentro de un método de objeto acceder a una propiedad directamente, especialmente viendo que llamar a otro método en ese objeto (que simplemente accederá a la propiedad directamente de todos modos y luego lo devolverá) es solo un ejercicio inútil y derrochador (o he entendido mal la pregunta ).
fuente
La forma más pura de OO es evitar ambas y seguir la Ley de Deméter utilizando el enfoque de Dile No Pregunte .
En lugar de obtener el valor de la propiedad del objeto, que empareja estrechamente las dos clases, use el objeto como parámetro, por ejemplo
Donde la propiedad era un tipo nativo, por ejemplo, int, use un método de acceso, asígnele el nombre del dominio del problema, no del dominio de programación.
Estos le permitirán mantener la encapsulación y cualquier condición posterior o invariantes dependientes. También puede usar el método del setter para mantener cualquier condición previa o invariantes dependientes, sin embargo, no caiga en la trampa de nombrarlos setters, vuelva al Principio de Hollywood para nombrar cuando use el idioma.
fuente
Es mejor utilizar los métodos de acceso, incluso dentro del objeto. Estos son los puntos que me vienen a la mente de inmediato:
Debe hacerse con el interés de mantener la coherencia con los accesos realizados desde fuera del objeto.
En algunos casos, estos métodos de acceso podrían hacer algo más que acceder al campo; podrían estar haciendo algún procesamiento adicional (aunque esto es raro). Si este es el caso, acceder al campo directamente significaría que está perdiendo ese procesamiento adicional, y su programa podría fallar si este procesamiento siempre se realiza durante esos accesos.
fuente
Si te refieres a "la mayoría de encapsulación" por "purista", entonces normalmente declaro todos mis campos como privados y luego uso "this.field" desde la propia clase. Para otras clases, incluidas las subclases, accedo al estado de la instancia utilizando los captadores.
fuente
Descubrí que usar setters / getters hizo que mi código fuera más fácil de leer. También me gusta el control que da cuando otras clases usan los métodos y si cambio los datos, la propiedad almacenará.
fuente
Campos privados con propiedad pública o protegida. El acceso a los valores debe pasar por las propiedades y copiarse a una variable local si se usarán más de una vez en un método. Si y SOLAMENTE si tiene el resto de su aplicación totalmente ajustado, sacudido y optimizado de otra manera para que el acceso a los valores al pasar por sus propiedades asociadas se haya convertido en un cuello de botella (y eso nunca sucederá NUNCA, lo garantizo) en caso de que siquiera comience considerar permitir que cualquier otra cosa que no sean las propiedades toque directamente sus variables de respaldo.
Los desarrolladores de .NET pueden usar propiedades automáticas para hacer cumplir esto, ya que ni siquiera puede ver las variables de respaldo en el momento del diseño.
fuente
Depende. Es más una cuestión de estilo que cualquier otra cosa, y no hay una regla estricta.
fuente
Puedo estar equivocado porque soy autodidacta, pero NUNCA utilizo propiedades públicas en mis clases de Java, siempre son privadas o protegidas, por lo que el código externo debe acceder mediante getters / setters. Es mejor para fines de mantenimiento / modificación. Y para el código de la clase interna ... Si el método getter es trivial, uso la propiedad directamente, pero siempre uso los métodos setter porque podría agregar código fácilmente para disparar eventos si lo deseo.
fuente
Si no edito la propiedad,
get_property()
usaré un método público a menos que sea una ocasión especial, como un objeto MySQLi dentro de otro objeto, en cuyo caso haré pública la propiedad y me referiré a ella como$obj->object_property
.Dentro del objeto siempre es $ this-> propiedad para mí.
fuente
Bueno, parece que con la implementación predeterminada de las propiedades de C # 3.0, la decisión se toma por usted; TIENE que establecer la propiedad utilizando el establecedor de propiedades (posiblemente privado).
Personalmente, solo uso el miembro posterior privado cuando no hacerlo causaría que el objeto caiga en un estado menos que deseable, como cuando se inicializa o cuando se trata de almacenamiento en caché / carga diferida.
fuente
Me gusta la respuesta de cmcculloh , pero parece que la más correcta es la de Greg Hurlman . Use getter / setter todo el tiempo si comenzó a usarlos desde el principio y / o está acostumbrado a trabajar con ellos.
Como acotación al margen, personalmente encuentro que usar getter / setter hace que el código sea más fácil de leer y depurar más adelante.
fuente
Como se indica en algunos de los comentarios: a veces debería, a veces no. La gran parte de las variables privadas es que puedes ver todos los lugares en los que se utilizan cuando cambias algo. Si su getter / setter hace algo que necesita, utilícelo. Si no importa, tú decides.
Se podría hacer el caso opuesto de que si usa el getter / setter y alguien cambia el getter / setter, tienen que analizar todos los lugares donde el getter y el setter se usan internamente para ver si estropea algo.
fuente