.net fluent-interface

.net - fluent api



¿Hay alguna desventaja al devolver esto en lugar de anular? (7)

¿No es así como se construyen las "interfaces fluidas", como las que utiliza JQuery? Se supone que uno de los beneficios es la legibilidad del código (aunque la entrada de wikipedia en http://en.wikipedia.org/wiki/Fluent_interface menciona que algunos no lo pueden leer). Otro beneficio es la concisión del código, se pierde la necesidad de establecer propiedades en 7 líneas de código y luego se llama a un método en ese objeto en la 8ª línea.

Martin Fowler (quien acuñó el término aquí - http://martinfowler.com/bliki/FluentInterface.html ) dice que hay más en las interfaces fluidas que en el encadenamiento de métodos, sin embargo, el encadenamiento de métodos es una técnica común para usar con interfaces fluidas.

EDITAR: en realidad estaba volviendo aquí para editar mi respuesta y agregar que no hay inconveniente en devolver esto en lugar de vacío de manera mensurable, cuando vi el comentario de George señalando que me olvidé de discutir el tema de la pregunta. Perdón por el dilema inicial "sin sentido".

Digamos que en lugar de devolver el método void devolvió una referencia a la clase, incluso si no tenía un sentido semántico particular. Me parece que le daría más opciones sobre cómo se llaman los métodos, lo que le permite usarlo en un estilo de interfaz fluida y no puedo pensar en ninguna desventaja ya que no tiene que hacer nada con el valor de retorno (incluso almacenarlo).

Supongamos que se encuentra en una situación en la que desea actualizar un objeto y luego devolver su valor actual. en lugar de decir

myObj.Update(); var val = myObj.GetCurrentValue();

podrás combinar las dos líneas para decir

var val = myObj.Update().GetCurrentValue();

EDITAR: Le pregunté a continuación por un capricho, en retrospectiva, estoy de acuerdo en que es probable que sea innecesario y complicado, sin embargo, mi pregunta con respecto a devolver esto en lugar de vacío se mantiene.

En una nota relacionada, ¿qué piensan ustedes de tener el lenguaje incluye un nuevo trozo de azúcar sintáctica?

var val = myObj.Update()<.GetCurrentValue();

Este operador tendría un orden de precedencia bajo para que myObj.Update () se ejecute primero y luego llame a GetCurrentValue () en myObj en lugar del retorno nulo de la Actualización.

En esencia, me estoy imaginando un operador que dirá "llamar al método en el lado derecho del operador en el primer objeto válido a la izquierda". ¿Alguna idea?


Creo que como política general, simplemente no tiene sentido. El método de encadenamiento de esta manera funciona con una interfaz definida correctamente, pero solo es apropiado si tiene sentido semántico.

Su ejemplo es uno primordial en el que no es apropiado, porque no tiene sentido semántico.

Del mismo modo, su azúcar sintáctica es innecesaria con una interfaz fluida correctamente diseñada.

Las interfaces fluidas o el encadenamiento de métodos pueden funcionar muy bien, pero deben diseñarse cuidadosamente.


El marco NeXTSTEP Objective-C solía usar este patrón. Fue descontinuado en ese marco una vez que los objetos distribuidos (llamadas a procedimientos remotos, básicamente) se agregaron al lenguaje -una función que retornaba a self tenía que ser una invocación sincrónica, ya que el sistema de objetos distribuidos veía el tipo de retorno y suponía que el llamante necesitaría para saber el resultado de la función.


La única desventaja que puedo ver es que hace que la API sea un poco más confusa. Digamos que tiene algún objeto de colección con un método remove () que normalmente volvería vacío. Ahora desea devolver una referencia a la colección en sí. La nueva firma se vería así:

public MyCollection remove(Object someElement)

Solo mirando la firma, no está claro si está devolviendo una referencia a la misma instancia. Tal vez MyCollection es inmutable y estás devolviendo una nueva instancia. En algunos casos, como aquí, necesitaría cierta documentación externa para aclarar esto.

De hecho, me gusta esta idea, y creo que se habló de la adaptación de todos los métodos nulos en Java7 para devolver una referencia a ''esto'', pero finalmente no funcionó.


Regresar "self" o "this" es un patrón común, a veces denominado "encadenamiento de métodos" . En cuanto a su azúcar de sintaxis propuesta, no estoy tan seguro. No soy un chico .NET, pero no me parece terriblemente útil.


Sé que en Java están pensando en hacer este comportamiento estándar para los métodos nulos. Si lo haces, no necesitas el azúcar sintáctico adicional.

El único inconveniente que puedo pensar es el rendimiento. Pero eso es medido con facilidad. Me pondré en contacto contigo con los resultados en unos minutos :-)

Editar:

Devolver una referencia es un poco más lento que devolver el vacío ... qué sorpresa. Entonces ese es el único inconveniente. Un par de tics más cuando llama a su función.


A primera vista, puede verse bien, pero para una interfaz coherente necesitarás que todos los métodos devuelvan una referencia a esto (que tiene sus propios problemas).

Digamos que tienes una clase con dos métodos GetA que devuelve esto y GetB que devuelve otro objeto:

Entonces puede llamar obj.GetA (). GetB (), pero no obj.GetB (). GetA (), que al menos no parece consistente.

Con Pascal (y Visual Basic) puede llamar a varios métodos del mismo objeto.

with obj .GetA(); .GetB(); end with;

El problema con esta característica es que fácilmente puede escribir código que es más difícil de entender de lo que debería ser. Además, agregar un nuevo operador probablemente lo haga aún más difícil.