¿Cómo accedería a las propiedades del objeto desde dentro de un método de objeto?[cerrado]

StackOverflow https://stackoverflow.com/questions/126

  •  08-06-2019
  •  | 
  •  

Pregunta

¿Cuál es la forma "purista" o "correcta" de acceder a las propiedades de un objeto desde un método de objeto que no es un método getter/setter?

Sé que desde fuera del objeto deberías usar un captador/definidor, pero desde dentro simplemente harías:

Java:

String property = this.property;

PHP:

$property = $this->property;

o harías:

Java:

String property = this.getProperty();

PHP:

$property = $this->getProperty();

Perdónenme si mi Java está un poco apagado, hace un año que no programo en Java...

EDITAR:

Parece que la gente asume que estoy hablando únicamente de variables/propiedades privadas o protegidas.Cuando aprendí OO, me enseñaron a usar captadores/definidores para cada propiedad, incluso si era pública (y en realidad me dijeron que nunca hiciera pública ninguna variable/propiedad).Por lo tanto, es posible que esté 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 no necesitan captadores y definidores, lo que va en contra de lo que me enseñaron y de lo que estaba hablando, aunque tal vez eso deba discutirse como Bueno.Sin embargo, probablemente sea un buen tema para una pregunta diferente...

¿Fue útil?

Solución

Esto tiene potencial de guerra religiosa, pero me parece que si estás usando un getter/setter, deberías usarlo internamente también; usar ambos conducirá a problemas de mantenimiento en el futuro (por ejemplo,alguien agrega código a un configurador que necesidades para ejecutarse cada vez que se establece esa propiedad, y la propiedad se establece internamente sin que se llame a ese definidor).

Otros consejos

Personalmente, siento que es importante mantener la coherencia.Si tiene captadores y definidores, 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 desees cambiar la forma en que funciona ese campo.Tal vez debería calcularse sobre la marcha o tal vez le gustaría utilizar 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.

Me sorprende bastante lo unánime que es el sentimiento de que getters y los armadores están muy bien.Sugiero el artículo incendiario de Allen Holub "Los captadores y definidores son malvados".Por supuesto, el título es impactante, pero el autor hace puntos válidos.

Básicamente, si tienes getters y setters 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 llame getter.

Además, desde un punto de vista estrictamente orientado a objetos, los objetos deberían responder a mensajes (métodos) que correspondan a su (con suerte) responsabilidad única.La gran mayoría de getters y setters no tienen sentido para sus objetos constituyentes;Pen.dispenseInkOnto(Surface) tiene más sentido para mí que Pen.getColor().

Los captadores y definidores también alientan a los usuarios de la clase a solicitar algunos datos al objeto, realizar un cálculo y luego establecer algún otro valor en el objeto, mejor conocido como programación procedimental.Sería mejor que simplemente le dijeras al objeto que hiciera lo que tú ibas a hacer en primer lugar;también conocido como el Experto en información modismo.

Los captadores y definidores, sin embargo, son males necesarios en los límites de las capas: interfaz de usuario, persistencia, etc.Acceso restringido a las partes internas de una clase, como la palabra clave amigo de C++, el acceso protegido al paquete de Java, el acceso interno de .NET y el Patrón de clase de amigo puede ayudarle a reducir la visibilidad de getters y establece solo para aquellos que los necesitan.

Depende de cómo se utilice la propiedad.Por ejemplo, digamos que tiene un objeto de estudiante que tiene una propiedad de nombre.Puede utilizar su método Get para extraer el nombre de la base de datos, si aún no se ha recuperado.De esta manera estás reduciendo las llamadas innecesarias a la base de datos.

Ahora digamos que tiene un contador de enteros privado en su objeto que cuenta la cantidad de veces que se ha llamado el nombre.Es posible que no desee utilizar el método Get desde dentro del objeto porque produciría un recuento no válido.

PHP ofrece innumerables formas de manejar esto, incluidos métodos mágicos. __get y __set, pero prefiero captadores y definidores explícitos.Este es el por qué:

  1. La validación se puede colocar en establecedores (y captadores para el caso)
  2. Intellisense funciona con métodos explícitos.
  3. No hay duda de si una propiedad es de solo lectura, solo de escritura o de lectura y escritura.
  4. La recuperación de propiedades virtuales (es decir, valores calculados) tiene el mismo aspecto que las propiedades normales
  5. Puede establecer fácilmente una propiedad de objeto que nunca se define en ningún lugar y que luego queda sin documentar.

¿Me estoy excediendo aquí?

Tal vez ;)

Otro enfoque sería utilizar un método privado/protegido para realizar la obtención (almacenamiento en caché/db/etc), y un contenedor público que incremente el recuento:

PHP:

public function getName() {
    $this->incrementNameCalled();
    return $this->_getName();
}

protected function _getName() {
    return $this->name;
}

y luego desde dentro del propio objeto:

PHP:

$name = $this->_getName();

De esta manera, aún puede usar ese primer argumento para otra cosa (como enviar una bandera para indicar si se deben usar o no datos almacenados en caché aquí).

Debo no entender 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, el cual debería llamar a un captador.

Entonces yo diría que dentro de un método de objeto acceder a una propiedad directamente, especialmente considerando que llamar a otro método en ese objeto (que de todos modos accederá a la propiedad directamente y luego la devolverá) es solo un ejercicio inútil y inútil (o he entendido mal la pregunta). ).

Si por "purista" te refieres a "mayor encapsulación", normalmente declaro todos mis campos como privados y luego uso this.field desde dentro de la clase misma, pero todas las demás clases, incluidas las subclases, acceden al estado de la instancia mediante captadores.

Yo diría que es mejor utilizar los métodos de acceso incluso dentro del objeto.Estos son los puntos que me vienen a la mente de inmediato:

1) Debe hacerse en aras de mantener la coherencia con los accesos realizados fuera del objeto.

2) En algunos casos, estos métodos de acceso podrían estar haciendo más que simplemente acceder al campo;podrían estar realizando algún procesamiento adicional (aunque es raro).Si este es el caso, al acceder directamente al campo se perdería ese procesamiento adicional y su programa podría salir mal si este procesamiento se realiza siempre durante esos accesos.

La forma purista de OO es evitar ambos y seguir el Ley de Deméter usando el decir no preguntar acercarse.

En lugar de obtener el valor de la propiedad del objeto, que parejas estrechamente las dos clases, use el objeto como parámetro, p.

  doSomethingWithProperty() {
     doSomethingWith( this.property ) ;
  }

Cuando la propiedad era de tipo nativo, p.int, use un método de acceso, asígnele el nombre del dominio del problema, no el dominio de programación.

  doSomethingWithProperty( this.daysPerWeek() ) ;

Estos le permitirán mantener la encapsulación y las condiciones posteriores o invariantes dependientes.También puede usar el método setter para mantener cualquier condición previa o invariante dependiente; sin embargo, no caiga en la trampa de nombrarlos setters; vuelva al Principio de Hollywood para nombrar cuando use el modismo.

Descubrí que el uso de setters/getters hizo que mi código fuera más fácil de leer.También me gusta el control que brinda cuando otras clases usan los métodos y si cambio los datos que almacenará la propiedad.

Campos privados con propiedades públicas o protegidas.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 SÓLO si tiene el resto de su aplicación totalmente modificado, mejorado y optimizado hasta el punto de que acceder a los valores a través de sus propiedades asociadas se haya convertido en un cuello de botella (y eso NUNCA sucederá, lo garantizo) debería siquiera comenzar. considerar permitir que cualquier otra cosa que no sean las propiedades toque sus variables de respaldo directamente.

Los desarrolladores de .NET pueden usar propiedades automáticas para hacer cumplir esto, ya que ni siquiera pueden ver las variables de respaldo en el momento del diseño.

Si no edito la propiedad, usaré un get_property() método público a menos que sea una ocasión especial, como un objeto MySQLi dentro de otro objeto, en cuyo caso simplemente haré pública la propiedad y me referiré a ella como $obj->object_property.

Dentro del objeto siempre es $this->property para mí.

Eso depende.Es más una cuestión de estilo que cualquier otra cosa, y no existe una regla estricta.

Puedo estar equivocado porque soy autodidacta, pero NUNCA uso propiedades públicas en mis clases de Java, siempre son privadas o están protegidas, por lo que el código externo debe acceder mediante captadores/definidores.Es mejor para fines de mantenimiento/modificación.Y para el código de clase interno...Si el método getter es trivial, uso la propiedad directamente, pero siempre uso los métodos setter porque fácilmente podría agregar código para activar eventos si lo deseo.

Bueno, parece que con la implementación predeterminada de las propiedades de C# 3.0, la decisión la toma usted;TIENES que configurar la propiedad usando el configurador de propiedad (posiblemente privado).

Personalmente, solo uso el miembro privado detrás 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.

Me gusta la respuesta de cmcculloh, pero parece que la más correcta es la respuesta de Greg Hurlman.Utilice getter/setters todo el tiempo si empezó a usarlos desde el principio y/o está acostumbrado a trabajar con ellos.

Además, personalmente encuentro que el uso de getter/setters hace que el código sea más fácil de leer y depurar más adelante.

Como se indica en algunos de los comentarios:A veces deberías, a veces no deberías.Lo mejor 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, úselo.Si no importa, tú decides.

Se podría plantear el caso opuesto: si usa el getter/setter y alguien cambia el getter/setter, tendrá que analizar todos los lugares en los que se usa el getter y el setter internamente para ver si estropea algo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top