¿La “convención sobre la configuración” no viola los principios básicos de programación?


51

Estaba mirando el framework MVPM de WPF Caliburn.Micro y leí que muchas cosas estándar se basan en convenciones de nomenclatura .

Por ejemplo, el enlace automático de propiedades en la vista a propiedades en el modelo de vista. Aunque esto parece ser conveniente (elimina algo de código repetitivo), mi primera reacción instintiva es que no es completamente obvio para un nuevo programador que leerá este código. En otras palabras, la funcionalidad de la aplicación no se explica completamente por su propio código, sino también por la documentación del marco.

EDITAR:

Entonces este enfoque se llama convención sobre la configuración. Como no pude encontrar ninguna pregunta al respecto, modifiqué mi pregunta:

Mi pregunta es:

¿Es la convención sobre la configuración una forma correcta de simplificar las cosas, o está violando algunos principios de programación (y si es así, cuáles)?


8
La mayoría de los enfoques / principios violan algunos otros enfoques / principios hasta cierto punto. Es principalmente una cuestión de prioridades y compensaciones.
Joachim Sauer

1
Es cierto, pero la diferencia en mi pregunta me parece un poco extraña y, por lo tanto, estoy interesado en las compensaciones específicas y los principios posiblemente violados cuando se utiliza la convención sobre la configuración.
Geerten

El concepto de trazabilidad de software es relevante aquí. Los programadores confían en herramientas como grep, pero necesitan mejores herramientas para rastrear los usos del código generado. Por ejemplo, las herramientas deberían hacer más explícito que la clase css "user-id" está relacionada con el método generado getUserId () y la columna de la tabla user_id.
Macneil

Respuestas:


49

No considero "una aplicación debe explicarse completamente por su propio código" un principio de programación fundamental. Hay muchísimas cosas que no se explican simplemente mirando el código de una aplicación. Además de conocer las cosas básicas del lenguaje de programación en sí (sintaxis y semántica), debe conocer las convenciones. Si un identificador en Java comienza con una letra mayúscula, es un tipo. Hay muchas de estas convenciones que necesita saber.

La convención sobre la configuración se trata de reducir la cantidad de decisiones que el programador debe tomar sobre las cosas. Para algunas cosas esto es obvio: nadie consideraría tener un lenguaje en el que la mayúscula de los tipos es algo que necesita declarar en la parte superior de su programa, pero para otras cosas no es tan obvio.

Equilibrar la convención y la configuración es una tarea difícil. Demasiada convención puede hacer que el código sea confuso (tome las variables implícitas de Perl, por ejemplo). Demasiada libertad por parte del programador puede dificultar la comprensión de los sistemas, ya que el conocimiento obtenido de un sistema rara vez es útil al estudiar otro.

Un buen ejemplo de dónde la convención ayuda al programador es cuando escribe complementos de Eclipse. Al mirar un complemento que nunca he visto, inmediatamente sé muchas cosas al respecto. La lista de dependencias está en MANIFEST.MF, los puntos de extensión están en plugin.xml, el código fuente está bajo "src", y así sucesivamente. Si estas cosas dependieran del programador, cada plugin de Eclipse sería diferente y la navegación de código sería mucho más difícil.


44
+1: el desarrollo de software es lo suficientemente complicado como es. Si puede evitar la complejidad en las cosas que tiene control, hágalo. Guarde la complejidad para los lugares que absolutamente la necesita.
scrwtp

1
Gracias por la explicación clara sobre la diferencia y el equilibrio.
Geerten

3
"Si un identificador en Java comienza con una letra mayúscula, es un tipo". - si es un tipo depende del contexto de sintaxis y no del patrón de nomenclatura, las convenciones de nomenclatura de Java no afectan la 'configuración de compilación'. ¿Estás seguro de que es un ejemplo válido? El último ejemplo tampoco es correcto: se trata de "convenciones de configuración", no de "convención sobre configuración". Estás diciendo cosas correctas pero tienen poco que ver con el principio subj.
Den

44
No sobreanalice los ejemplos, son solo ejemplos. El primero es solo un ejemplo de una convención, el último es un ejemplo donde la convención es algo bueno. El ejemplo de Perl es un ejemplo donde demasiadas convenciones (implicaciones) son algo malo (OMI, debo agregar).
JesperE

1
Lo que odio es cuando la convención sobre la configuración se convierte en convención sin configuración ... en el último caso, tiende a quedar atrapado con una base de código, puede ser difícil de integrar con otras herramientas.
Andy

77

Le dio +1 a @JesperE y le gusta agregar algo:

¿Está violando algunos principios de programación?

Sí, "la convención sobre la configuración" viola el principio "explícito es mejor que implícito" (eche un vistazo, por ejemplo, a "Zen-Of-Python" ).

Por otro lado, la "configuración sobre la convención" opuesta tiende a violar "Simple es mejor que complejo", y lo que es peor, viola el principio DRY de una manera sutil, ya que debe repetir los nombres utilizados en su código también en su configuración .


44
¡Esa es la respuesta más directa a la pregunta!
Joachim Sauer

Esta es la respuesta correcta real entre los dos más votados.
Den

+1 para "explícito es mejor que implícito"
Justin Ohms

12
Mi parte favorita de esta respuesta es que resalta implícitamente la realidad de que los principios del buen desarrollo de software a menudo se encuentran en tensión entre sí. La ingeniería consiste en equilibrar esas tensiones adecuadamente para su contexto y aplicación específicos.
Chris Krycho

Buena respuesta. Para ampliar el comentario de @Chris Krycho, lo bueno de los estándares o principios de software es que tiene tantos para elegir. :-)
user949300

9

Algunas de las "convenciones sobre la configuración" se reducen a valores predeterminados razonables. Solo debería tener que configurar algo para usarlo para un propósito no estándar. Tengo que comparar Struts a Rails aquí. En Rails, tienes que poner tus "acciones / pantallas" en una carpeta y luego simplemente funcionan. En Struts, todavía tiene que ponerlos en una carpeta, pero también debe crear un nombre de acción Y un archivo JSP Y un nombre de formulario Y un bean de formulario Y especificar cómo funcionan estas tres cosas juntas en Struts-config. xml Y especifique que el formulario pertenece a la solicitud (RESTful). Si eso no es suficiente, el mapeo form / form-bean tiene su propia sección en Struts-config que luego se mapea independientemente a la sección de acción en el mismo archivo y todo depende de cadenas escritas a mano en el archivo JSP para funcionar correctamente. Para cada pantalla, Eso es al menos 6 cosas que no deberías tener que hacer y tantas oportunidades para cometer un error. Creo que puede configurar la mayoría o todas esas cosas manualmente en Rails si lo necesita, pero 2/3 del tiempo de desarrollo de Struts se dedica a construir y mantener capas innecesarias de complejidad.

Para ser justos, Struts 1 fue diseñado cuando las personas portaban aplicaciones entre el escritorio y la web. La flexibilidad que Struts ha incorporado lo hace adecuado para todo lo que hace Rails, además de todo lo que una aplicación de escritorio necesitaría. Desafortunadamente, la montaña de configuración que permite esa flexibilidad es una gran bola y cadena para alguien que solo necesita escribir una aplicación web o simplemente una aplicación de escritorio.

Trabajé en algún lugar en el que dieron el siguiente paso y argumentaron: "Configuración sobre código ", pero al ver que se llevó a su extremo lógico, el resultado es que la configuración se convierte en un nuevo lenguaje de codificación. Era un juego de conchas donde la complejidad se empujaba sin ser domesticada de manera significativa. Y me dio una apreciación por todas las verificaciones de tipos y otras redes de seguridad que tiene un lenguaje de programación bien diseñado. Algún formato de archivo de configuración a medias que explota sin mensaje de error si agrega un espacio o un apóstrofe NO es una mejora sobre un lenguaje de programación de calidad que tiene suites de herramientas de edición y un compilador de calidad escrito para ello.

No puedo imaginar que tener valores predeterminados razonables viole cualquier principio teórico sobre extensibilidad y modularidad. Un programador de Ruby / Rails preferiría tener un póker en sus ojos que cambiar a un marco como Struts 1 donde todas las configuraciones se realizan explícitamente en múltiples archivos XML. No estoy discutiendo Rails vs. Struts EN GENERAL, pero esa convención puede ser una gran ganancia de productividad. Estas dos tecnologías son la comparación más extrema del mundo real que he encontrado.

Si trabaja en Java, consulte el ítem 2 de Joshua Bloch, "Java efectivo": "Considere un generador cuando se enfrente con muchos parámetros de constructor" págs. 11-16. Para la mayoría de los propósitos, se requieren algunos parámetros (configuración) y algunos son opcionales. La idea básica es requerir solo la configuración necesaria y solo hacer que el usuario (que podría ser otro programa) especifique opciones adicionales según sea necesario. Limpié un montón de código con este patrón hace un mes y brilla positivamente.


7

En otras palabras, la funcionalidad de la aplicación no se explica completamente por su propio código, sino también por la documentación del marco.

La funcionalidad de una aplicación que usa un marco siempre depende del marco, la convención sobre la configuración no hace una diferencia en ese sentido.

En mi experiencia, la convención sobre la configuración no solo hace que el código sea más legible, sino que también reduce la posibilidad de introducir errores sutiles (especialmente copiar-pegar-errores).

Por ejemplo, supongamos que en algún marco A, el evento FooBaractiva una llamada a handleFooBar. En otro marco B, esta correlación se configura en algún lugar de un archivo XML.

Entonces, en A, es simplemente

handleFooBar() {
   ...
}

y a menos que haya escrito mal FooBar, se llamará siempre que ocurra FooBar.

En B, es de nuevo

handleFooBar() {
   ...
}

pero también

<eventconfiguration>
  <event>
    <type>FooBar</type>
    <handler>handleFooBar</handler>
  </event>
</eventconfiguration>

Con cientos de cosas para configurar de esta manera, es demasiado fácil crear accidentalmente un error sutil como

<eventconfiguration>
  <event>
    <type>BarFoo</type>
    <handler>handleFooBar</handler>
  </event>
</eventconfiguration>

porque después de copiar y pegar, solo hemos cambiado <type>pero nos olvidamos de cambiar <handler>.

Dado que esos archivos de configuración son grandes y monótonos, es menos probable que alguien encuentre el error mediante la corrección de pruebas que un error similar en el código del programa real.


1
+1: evitar la configuración repetitiva, aburrida de escribir, difícil de leer y casi siempre obvia es la principal ventaja de la convención sobre la configuración.
Joachim Sauer

-1

Puede estar violando algunos principios, pero al mismo tiempo obedece a uno de los principios de diseño más fundamentales, SRP (Principio de responsabilidad única).


2
Usar convenciones no tiene nada que ver con la responsabilidad individual. Podría estar usando una convención y haciendo 100 cosas en ella.
Suamere
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.