¿Cuáles son las ventajas de un getter / setter "combinado" frente a métodos individuales?

12

Esto es lo que yo llamo un método "combinado" getter / setter (de jQuery):

var foo = $("<div>This is my HTML</div>"),
    myText;

myText = foo.text(); // myHTML now equals "This is my HTML" (Getter)
foo.text("This is a new value"); // The text now equals "This is a new value")

Esta es la misma lógica con métodos separados (teóricos):

var foo = $("<div>This is my HTML</div>"),
    myText;

myText = foo.getText(); // myHTML now equals "This is my HTML" (Getter)
foo.setText("This is a new value"); // The text now equals "This is a new value")

Mi pregunta:

Al diseñar una biblioteca como jQuery, ¿por qué decidirías ir a la primera ruta y no a la segunda? ¿No es el segundo enfoque más claro y fácil de entender de un vistazo?

Levi Hackwith
fuente
66
Martin Fowler no es fanático de lo que él llama "setters getter sobrecargados": martinfowler.com/bliki/OverloadedGetterSetter.html
vaughandroid
1
Me gustaba el método de división get / set (pensando que hacía que el código fuera más "obvio"), pero estoy encontrando el patrón getter / setter sobrecargado más atractivo en estos días. Puede hacer que el código sea más limpio. Nunca me ha gustado el compromiso del señor Fowler. Me parece que es lo peor de ambos mundos.
Brian Knoblauch el
El único argumento real de Martin Fowler en su contra es cuando el 'captador' pasa en una discusión, en cuyo caso es confuso para el lector que no parece un captador. A partir de ahora, he concluido que si se atiene a la convención de que el getter no toma argumentos, y el setter toma uno, que, junto con los comentarios claros de la API, el enfoque jQuery / Angular debería estar bien. Por ahora.
zumalifeguard

Respuestas:

13

Puramente especulando aquí, pero me inclinaría a creer que los desarrolladores de jQuery que usaron mucho del estilo funcional en la estructuración de jQuery claramente tienen una inclinación hacia el paradigma funcional.

Dado que, en el paradigma funcional, existe una fuerte cultura de reducción de la redundancia, y se podría argumentar que el segundo enfoque tiene redundancia innecesaria. El primer enfoque puede no estar claro para alguien acostumbrado a todos los lenguajes imperativos comunes, pero indiscutiblemente está haciendo más con menos al tener solo un método en lugar de dos. Esto puede ser peligroso, pero es una herramienta común en el paradigma funcional y algo a lo que uno se acostumbra rápidamente.

Practique en el paradigma funcional y rápidamente superará ese deseo hacia la ceremonia y aprenderá a apreciar la capacidad de hacer más con menos. Aunque esta es reconociblemente una opción subjetiva basada en la preferencia de la misma manera, muchas personas tienen preferencias con respecto a la gestión de espacios en blanco. De esta manera, no digo que una forma sea mejor, sino que son cosas a las que la gente se acostumbra, por lo que es probable que jQuery tenga el enfoque que tiene.

Esta sería la razón por la que creo que los desarrolladores de jQuery hicieron esto y, en general, es por qué alguien podría adoptar este enfoque.

Jimmy Hoffa
fuente
2
De acuerdo, además agregaría el deseo de reducir el tamaño de JS tanto como sea posible.
Matt S
-1 para los puntos imperativo / detallado y funcional / implícito.
3
@MattFenwick No pretendo ofender, ¿estás diciendo que no es cierto que el paradigma funcional se inclina hacia la implicitud donde el paradigma imperativo se inclina hacia la explicidad? No digo que ninguno sea mejor, solo que uno puede acostumbrarse a uno u otro, lo que haría que haga las cosas automáticamente de esa manera en lugar de la otra (esto es igual para ambos)
Jimmy Hoffa
@ Jimmy no hay problema; mi punto era solo que, en mi experiencia, he encontrado que la implicidad / explicidad es ortogonal a FP / imperativo.
@MattFenwick podría serlo, pero yo diría que aparte de la inferencia de tipos que permite mucha implícita y es común al sistema de tipos HM, otras cosas comunes a los lenguajes FP se inclinan hacia la implícitamente, así como todos los operadores como funciones donde la función no tiene un nombre explícito, solo un símbolo que se espera que aprenda y conozca implícitamente, o el uso común de listas o tuplas que requieren un conocimiento implícito del significado y la ubicación del miembro en lugar de DU (piense en cómo funciona la mónada del escritor). También tiendo a ver una coincidencia de nombres de parámetros de una sola letra, pero puede que tengas razón
Jimmy Hoffa
2

La forma

foo.text("This is a new value"); 

puede implicar una serie de cosas. Más comúnmente, sugiere un fooobjeto, con un método llamado textaceptar una cadena, que hace algo . No hay implicación de que esta sea una propiedad en absoluto.

En muchos idiomas, esto puede considerarse una forma abreviada de

var result = foo.text("This is a new value"); 

donde se descarta el resultado. Por lo tanto, este enfoque es demasiado ambiguo para ser una forma efectiva de establecer una propiedad (desde el punto de vista de la legibilidad del código).

Robert Harvey
fuente
¡Este es un punto excelente! Me puse las gafas FP cuando leí JavaScript y las cosas se ven de manera diferente, así que ni siquiera pensé en esto, pero si viera un código como este en C #, tendría exactamente la reacción a la que te estás refiriendo: "¿Qué hace este método? ?? ".
Jimmy Hoffa
1

Es un poco especulativo, pero aquí está mi oportunidad.

jQuery abraza completamente la naturaleza funcional de javascript. Eso es lo que lo hace tan increíble, pero puede dejar a muchos desarrolladores rascándose la cabeza cuando provienen de un lenguaje más puramente OO como java. Parece romper todas las convenciones y buenas prácticas.

El lenguaje funcional tiende a poner énfasis en una sintaxis declarativa. Tiende a leerse como una declaración de un hecho en lugar de como comandos. Ejemplo

var eligible = customers.where(c => c.age > 30);

que puede leerse como "el cliente elegible son los clientes cuya edad es mayor de 30 años". Por restricción, el lenguaje imperativo se lee como una secuencia de comando

for (customer in customers)
    if (customer.age > 30)
        eligible.add(customer)

Puede leerse como "Verifique a cada cliente y, si tiene más de 30 años, agréguelos a la colección elegible"

Agregar aa sety una getoperación haría que jQuery se sintiera como una biblioteca imprescindible. Puede restringir la forma de leer las siguientes declaraciones

// The element tag have an html of <p>hello</p>
$("#element").html("<p>hello</p>"); 

// content represent the html of the element tag
var content = $("#element").html();


//Imperative style

// Set the element tag to an inner html of <p>hello</p>
$("#element").setHtml("<p>hello</p>");

//Get the html of #element, and put it in the content variable
var content = $("#element").getHtml();

Al mantener el verbo de acciones fuera de la API jQuery, lo hicieron sentir como una API declarativa. Da una sensación consistente y funcional a la biblioteca. Por eso creo que sobrecargaron las palabras clave.

Laurent Bourgault-Roy
fuente
1

Hace que se parezca más a las propiedades , que se introdujeron recientemente en JavaScript y, por lo tanto, aún no se usan ampliamente, especialmente en bibliotecas como jQuery que están destinadas a ayudar a eliminar las incompatibilidades del navegador.

Si alguna vez ha mirado una definición de clase llena de tales propiedades, los prefijos "set" y "get" parecen superfluos, porque la adición del parámetro de valor ya le dice que es un setter. Martin Fowler hace un buen punto acerca de los captadores que requieren un parámetro, pero incluso entonces, dentro de ese contexto, el parámetro de valor adicional denota claramente un establecedor, así como el hecho de que un colocador rara vez aparece en el lado derecho de una tarea. Y cuando está escribiendo código, debe mirar la documentación de la biblioteca de todos modos.

Como solo solicitó ventajas, no cubriré las desventajas.

Karl Bielefeldt
fuente