Combinando getters y setters

16

Las bibliotecas de JavaScript, como jQuery, combinan 'getters' y 'setters' en la interfaz de programación, por ejemplo:

 $('element').css({'color','blue'});

establecerá el color o

 $('element').css();

obtendrá el CSS para un elemento.

¿Existe un nombre para ese patrón y es una buena práctica usarlo en aplicaciones?

Yannis
fuente

Respuestas:

12

Martin Fowler lo nombró recientemente Getter y setter sobrecargados en este artículo :

He estado hurgando en Javascript recientemente y una cosa que me llamó la atención es el hábito de usar el mismo nombre de función para un getter y un setter. Entonces, si desea averiguar la altura de su banner en jQuery, usaría $("#banner").height()y si desea cambiar la altura que usaría $("#banner").height(100).

Esta convención me es familiar, ya que fue utilizada por Smalltalk. Puede obtener un valor con banner heighty cambiarlo con banner height: 100. Saber que era una convención de Smalltalk es suficiente para esperar que me guste, ya que tengo un amor distante pero permanente por ese idioma. Pero incluso las mejores cosas tienen fallas, y no puedo ocultar mi disgusto por este estilo de codificación ...

A pesar de esta preferencia, debe seguir las convenciones del idioma con el que está tratando. Si volviera a escribir Smalltalk, aún lo usaría height:100para mantener la coherencia con las convenciones del lenguaje. Javascript, sin embargo, no destaca por tener convenciones fuertes, por lo que aquí preferiría evitar esta convención, incluso si es utilizada por jQuery ...

louisgab
fuente
1
Aunque normalmente estoy de acuerdo con la mayoría de lo que dice Fowler, no estoy de acuerdo con su disgusto por esto. Su razonamiento es que JavaScript no tiene convenciones fuertes como Smalltalk, lo que lo hace utilizable allí. Sin embargo, jQuery tiene convenciones fuertes, y JavaScript no es jQuery. jQuery es un marco.
CaffGeek
@ Chad, tengo que estar en desacuerdo con tu lectura de eso. Su argumento es que carece de explicidad y coherencia. Él dice que lo usa en Smalltalk porque la coherencia con otros triunfa sobre sus preocupaciones. No está argumentando que las convenciones de Smalltalk de alguna manera mitigan o eliminan el problema.
Winston Ewert
2

Se llama "sobrecarga de métodos" en idiomas OO o "sobrecarga de funciones" en idiomas que no son OO.

Si es o no una buena práctica es un tema de casi tanto debate como getters / setters vs. miembros públicos. Aquellos que están a favor y en contra probablemente se esfuercen en los idiomas que tenían esta característica o no, y se establecen en sus formas. Lo uso y me gusta la práctica por varias razones:

  • El contexto en el que se usa bastante bien separa uno del otro.
  • Anteponer geto setal nombre del método agrega verbosidad.
  • Si hay múltiples captadores (por ejemplo, uno para inty uno para double), cambiar el tipo en el LHS de una asignación ( int x = foo.bar()vs. double x = foo.bar()) no requiere un cambio de código ( barAsInteger()vs. barAsDouble()) en el lado derecho si la clase proporciona ambos. La desventaja de esto es que a veces puede ser difícil saber exactamente qué método se está llamando simplemente mirando el código.
Blrfl
fuente
También se llama "sobrecarga de funciones" en C ++.
DeadMG
Ambos términos se aplican a C ++ porque tiene ambos métodos y funciones desnudas.
Blrfl
1

Dado que JavaScript no tiene propiedades reales (donde establecer un valor realmente puede ejecutar código), el patrón es uno que implementa el idioma de propiedad. (Incluso si lo llamas de otra manera).

Entonces, en los idiomas que implementan propiedades reales, debería hacer esto en su lugar:

element.css = ...
x = element.css

Si usara el patrón de JavaScript en un lenguaje que maneje propiedades, estaría haciendo algo anormal. Eso probablemente no sería una buena idea. Maneje las propiedades de la forma en que el lenguaje debe manejarlas, para que no confunda a las otras personas que trabajan con usted.

John Fisher
fuente
"donde establecer un valor realmente puede ejecutar código". Esto ya no es cierto. Ha sido parte de la especificación desde ECMA 5
Demian Brecht
@Demian: Pero JQuery funciona en navegadores que no implementan ECMA 5.
John Fisher
No mencioné nada sobre la compatibilidad entre navegadores, solo que la cita es incorrecta tal como está escrita.
Demian Brecht
@Demian: el texto "JavaScript no tiene propiedades reales" es correcto si supone que está utilizando las versiones de JavaScript más comúnmente disponibles. Como estamos discutiendo dentro de un contexto de implementación de JQuery, la declaración sería correcta. Sin embargo, gracias por señalar que las versiones más nuevas de JavaScript tienen propiedades verdaderas.
John Fisher
0

Creo que estas buscando properties

thekip
fuente
Ese es el nombre de la funcionalidad proporcionada en C # (¿y quizás otros lenguajes .NET?) Que es similar a esto, pero en realidad no es lo mismo.
Thomas Owens
Sin embargo, Wikipedia está de acuerdo: en.wikipedia.org/wiki/Property_(programming)
thekip
Gracias, en realidad no es posible que tenga algo que decir caso en el que se establece un sueldo o conseguir personas en una aplicación person.salary('10000')o person.salary()o similar.
Yannis
1
No veo como "Las propiedades se leen y escriben como campos", lo cual no es cierto en el ejemplo de la publicación original. Allí, se realizan llamadas a métodos explícitos. Es muy similar, pero no exactamente igual.
Thomas Owens
1
@yannis Esto no es correcto. JavaScript tiene una sintaxis para las propiedades, y no es lo que usted describió en la pregunta original. Consulte en.wikipedia.org/wiki/Property_(programming)#JavaScript para ver cómo implementar y usar propiedades en JavaScript.
Thomas Owens
0

Estoy totalmente en contra de algo que, por una razón muy sencilla: una clase, método o función solo debería hacer una cosa - en mi opinión, y la combinación de la gettery settermétodo a romper esa regla. Como resultado:

  1. El returnvalor de la función varía según si se ejecuta el bloque getter o setter . Este puede simplemente llevarte a una pesadilla de mantenimiento. Su método debe devolver un solo tipo de datos / objeto en cualquier caso - o devolución null, falseo lanzará una exceptionen caso de error.
  2. Escribir pruebas unitarias será más difícil ya que la función es responsable de dos funciones totalmente diferentes.
  3. Escribir documentación para tal método o función es más difícil por razones obvias.
  4. No será consistente cuando se necesiten múltiples métodos getter , como ya se mencionó en la Blrflrespuesta.
Mahdi
fuente