2009-01-11 12 views
13

¿Qué es una interfaz fluida? No puedo encontrar una buena definición de esto, pero lo único que obtengo son largos ejemplos de código en un idioma con el que no estoy muy familiarizado (por ejemplo, C++).Interfaces fluidas y abstracciones con fugas

Además, ¿qué es una abstracción con goteras?

Gracias

+1

Esto debería haberse publicado como dos preguntas separadas. –

Respuesta

9

una interfaz fluida un término acuñado Eric Evans y es simplemente otro nombre para el método de encadenamiento. Martin Fowler escribió un couple de articles sobre este tema, pero es más o menos el siguiente aspecto:

m_Window = window::with() 
    .width(l_Width) 
    .height(l_Height) 
    .title("default window") 
    .left(200) 
    .top(200) 
.create(); 

interfaz fluida se utiliza generalmente para crear parámetros con nombre en un idioma que no sea compatible con ellos (el nombre del parámetro del idioma en C++ por ejemplo), o en Idiomas Específicos del Dominio para hacer que el código se lea con mayor fluidez.

He visto que se utilizan para todo, desde bibliotecas de procesamiento de imágenes, bibliotecas de expresiones regulares, bibliotecas 3D. Otros ejemplos incluyen la construcción de estructuras de árbol, listas u otras estructuras de datos. Todo lo que requiere la construcción de objetos complejos (carga de parámetros) puede utilizar interfaces fluidas para hacerlo más legible. Por ejemplo, comparar el ejemplo anterior a la llamada de función CreateWindow:

::CreateWindow(
     "Window class", 
     "Window title", 
     dwStyle, X, Y, 
     nWidth, nHeight, 
     hWndPant, hMenu, 
     hInstance, NULL 
); 
+0

como el encadenamiento de jQuery? –

+0

Ha pasado un tiempo desde que hice algún desarrollo relacionado con la web, pero a juzgar por la documentación de jQuery, parece que sí lo es. –

+0

Esto es encadenamiento de métodos, interfaces no fluidas. Ver la cita de la respuesta de Rasmus anterior * "Ciertamente, el encadenamiento es una técnica común para usar con interfaces fluidas, pero la verdadera fluidez es mucho más que eso ..." * – Pacerier

5

Aquí es una interfaz normal de cada día:

public interface NotFluent 
{ 
    void DoA(); 
    void DoB(); 
    void DoC(); 
} 

Y aquí es una interfaz fluida:

public interface Fluent 
{ 
    Fluent DoA(); 
    Fluent DoB(); 
    Fluent DoC(); 
} 

La mayor parte La diferencia obvia es que cuando devolvemos un vacío, volvemos en su lugar una instancia del tipo de interfaz. Lo que se entiende es que la interfaz devuelta es la INSTANCIA ACTUAL, no una nueva instancia del mismo tipo. Por supuesto, esto no es exigible, y en el caso de objetos inmutables (como una cadena) es una instancia diferente, pero se puede considerar que es la misma instancia solo actualizada.

Éstos son ejemplos de su uso:

NotFluent foo = new NotFluentImpl(); 
foo.DoA(); 
foo.DoB(); 
foo.DoC(); 

Fluent bar = new FluentImpl(); 
bar.DoA().DoB().DoC(); 

Observe que la interfaz fluida es más fácil de usar al encadenar diferentes llamadas. IRL, revisa los métodos de extensión de Linq y cómo cada llamada está diseñada para fluir a otra. Ninguno de los métodos vuelve vacío, incluso si sería un resultado válido.

+0

¿No es este ejemplo simplemente un método de encadenamiento? Fowler señala que [* "muchas personas parecen equiparar las interfaces fluidas con Method Chaining" *] (http://www.martinfowler.com/bliki/FluentInterface.html). ¿Qué propiedad tiene el código anterior que lo hace una interfaz fluida en lugar de un simple método de encadenamiento? – Pacerier

+0

@Pacerier si le interesa dividir este cabello (y esa referencia no le sirve para nada a la distinción que el autor supuestamente ve), entonces, en lugar de dejar caer comentarios sobre cada respuesta, ¿por qué no responderla usted mismo? O si desea obtener más información sobre cómo dividir ese cabello, haga una nueva pregunta que se concentre en las distinciones entre los dos. Personalmente, no veo mucho. Definitivamente no es suficiente para hacer una distinción que valga la pena. Los veo inextricablemente unidos. Es solo que a veces los patrones surgen y otras no. No estoy interesado en la estética, supongo. – Will

+0

Re * "por qué no responderlo usted mismo" *, no tengo una respuesta, de ahí las preguntas. Y esto no es "dividir pelos", parece estar bastante claro que FluentInterface no es igual a Method Chaining. – Pacerier

1

En una interfaz fluida, los métodos de un objeto devolverán una referencia al objeto, para que pueda encadenar las llamadas al método.

Por ejemplo, en NValidate, lo hice para simplificar la validación de parámetros:

public City GetCity(string zipCode) 
{ 
    zipCode.Assert("zipCode").IsNotNullOrEmpty().HasLength(5,10).Matches("\\d[5]-\\d[4]"); 
    // Continue processing 
} 

No puedo hablar en Leaky abstracciones, sin embargo.

24

Una interfaz fluida es una API que le permite escribir código que se parece más o menos al inglés normal. Por ejemplo:

Find.All.Questions(Where.IsAnswered == true); 

El método de encadenamiento se utiliza generalmente como parte de la implementación, pero hay más que eso.Para citar Fowler:

También he notado un concepto erróneo común: muchas personas parecen igualar las interfaces fluidas con Method Chaining. Ciertamente, el encadenamiento es una técnica común para usar con interfaces fluidas, pero la verdadera fluidez es mucho más que eso.

es también a menudo llamada interna DSL, ya que la sintaxis se parece al de una conexión DSL, pero se implementa dentro de la lengua de acogida en lugar de ser procesado por un programa de análisis.

+0

Y ... ¿cuáles son los pros/contras de las interfaces fluidas? – Pacerier

3

una interfaz orientada a objetos es fluidez si métodos que se ejecutan para el efecto lado de retorno self, de modo que tales métodos se pueden encadenar juntos.

Encontré por primera vez interfaces fluidas en 1990 cuando la Interfaz Modula-3 Police (no lo estoy inventando) requirió que todos los métodos de inicialización devolvieran el objeto inicializado. Creo que este uso es anterior a la acuñación del término "interfaz fluida".

+0

En realidad, cuando OP dice "interfaz fluida", es muy probable que se refiera a la definición de Fowler de [FluentInterface] (http://www.martinfowler.com/bliki/FluentInterface.html). No solo las interfaces * fluidas * en general. – Pacerier

17

Una abstracción con goteras es una abstracción en la que los detalles de la realidad subyacente a menudo "se filtran".

All abstractions lie más o menos, pero a veces las abstracciones son tan malas para la realidad subyacente, que causa más daño de lo que ayuda.

Un ejemplo simple de "fuga" en una abstracción podría ser el tipo de flotador habitual. Parece representar números reales generales y puede usarlo para realizar cálculos básicos. Pero en algún momento se encuentra con un escenario en el que 1/3 * 3! = 1 o 1 + 10^-20 = 1. Ahí es cuando se filtran los detalles de la implementación real y se rompe la abstracción.

1

Gracias chicos.

Descripción excelente.

Mi pensamiento sobre las interfaces fluidas en el que estaban para la legibilidad. Siempre pude leer una cadena de métodos y cómo uno está relacionado con el método anterior/siguiente.

E.g. como el póster que publicó el ejemplo de validación (he escrito un código similar al anterior).

1

Neal Ford hace un buen trabajo explicando y dando ejemplos de Fluent Interface en su libro el 'Productive Programmer'.

objeto tradicional o 'frijol' con getters/setters:

Car car = new CarImpl(); 
MarketingDescription des = new MarketingDescriptionImpl(); 
desc.setType("Box"); 
desc.setSubtype("Insulated"); 
desc.setAttribute("length", "50.5"); 
desc.setAttribute("ladder", "yes"); 
desc.setAttribute("lining type", "cork"); 
car.setDescription(desc); 

Conoce la misma necesidad con una interfaz fluida:

Car car = Car.describedAs() 
    .box() 
    .length(50.5) 
    .type(Type.INSULATED) 
    .includes(Equipment.LADDER) 
    .lining(Lining.CORK); 
Cuestiones relacionadas