2012-03-16 12 views
5

Empecé a escribir una interfaz fluida y eché un vistazo a una pieza más antigua que Martin Fowler escribió en interfaces fluidas (que no me di cuenta que él y Eric Evans acuñaron el término). En la pieza, Martin menciona que los instaladores generalmente devuelven una instancia del objeto que se está configurando o en el que se está trabajando, lo que él dice es una violación de CQS.¿Son las interfaces fluidas una violación del Principio de Separación de Consulta de Comando?

La convención común en el mundo corchete es que modificador métodos son nulos, lo que me gusta, ya que sigue el principio de Command-Query Separation. Esta convención se interpone en el camino de una interfaz fluida , por lo que estoy dispuesto a suspender la convención para este caso .

Así que si mi interfaz fluida hace algo como:

myObject 
    .useRepository("Stuff") 
    .withTransactionSupport() 
    .retries(3) 
    .logWarnings() 
    .logErrors(); 

¿Es esta realmente una violación de SCC?

ACTUALIZACIÓN Apagué mi muestra para mostrar las advertencias de registro y los errores como comportamientos separados.

+0

¿El 'logWarningsAndErrors' devolver algo? Si no, ¿es realmente una interfaz fluida? –

+0

@ M.Babcock actualizó mi muestra. Seguro, 'logWarningsAndErrors' devuelve una interfaz a la que puedo agregar comportamientos adicionales. –

Respuesta

0

No. El patrón aquí es "Configuración". Dichos comandos de configuración devuelven el objeto de configuración como algo opuesto a algo no relacionado con el comando. Una violación de la segregación de comandos/Consulta ocurriría si los comandos que sirven el propósito de configuración devueltos algunos datos no relacionados, por ejemplo:

if (myObject.UseRepository("Stuff") > 1 && myObject.UseRepository("Bla") < 5) { 
    // oh, good, some invisible stuff internal to myObject is in right interval... 
} 
+2

sry, no entiendo tu respuesta, pero quiero hacerlo. ¿Puedes por favor expandirlo? "si tuvieras ..." ¿dónde? Además, no hay alteración del estado interno en su fragmento. veo la violación del principio de "dígame, no pregunte", pero eso es todo –

+0

Intenté reformular, hágamelo saber si todavía es difícil de entender ... –

9

Sí, lo es. Todos esos métodos obviamente devuelven algo, e igualmente obviamente tienen efectos secundarios (a juzgar por el hecho de que no hace nada con el valor de retorno, sin embargo, se molesta en llamarlos). Dado que la definición de CQS establece que los mutadores no deben devolver un valor, tenemos una violación clara en nuestras manos.

¿Pero le importa a usted que se haya violado el CQS? Si la interfaz fluida lo hace más productivo considerando todo, y si lo considera un patrón bien conocido con beneficios e inconvenientes igualmente conocidos, ¿por qué debería importar si viola el principio X en papel?

+0

¿Cómo es obvio que 'logWarningsAndErrors' devuelve algo? –

+0

@ M.Babcock: Técnicamente no lo es, solo a partir de ese fragmento. Me atrapaste. – Jon

+0

De acuerdo. ¿Por qué importa si viola el principio X, si te ayuda a usarlo? –

2

Viola este principio cuando cambia objetos pero no cuando solo devuelve un objeto nuevo.

var newObject = myObject 
    .useRepository("Stuff") 
    .withTransactionSupport() 
    .retries(3) 
    .logWarningsAndErrors(); 

Si myObject es sin cambios después de esta declaración, todo está bien. Generalmente hablado, una interfaz fluida viola el principio CQS, si, y solo si tiene efectos secundarios.

Sin embargo, la pregunta es si su ejemplo representa una consulta. ¿"Fluido" significa necesariamente "consulta"? Probablemente podría simplemente ser percibida como una interfaz fluida de acción donde el mismo objeto pasa de una acción a la siguiente.

+0

hm, pero el objetivo de la configuración es cambiar el objeto (sujeto a configuración) así que ¿para qué molestarse? –

+0

¿Qué diferencia hace si el objeto que se está modificando es una instancia nueva o una anterior? Cualquiera de esas 4 llamadas modifica el valor de retorno de la expresión (sea lo que sea) o no hace nada, por lo que debe omitirse. – Jon

+0

La pregunta es si modifica un objeto existente y devuelve un resultado al mismo tiempo, convirtiéndolo en un comando y una consulta al mismo tiempo. Debe ser un comando ** o ** una consulta. –

Cuestiones relacionadas