Un poco de antecedentes: como líder del equipo, uso NDepend aproximadamente una vez por semana para verificar la calidad de nuestro código. Especialmente la cobertura de prueba, las líneas de código y las métricas de complejidad ciclomática son invaluables para mí. Pero cuando se trata de ciclos de nivelación y dependencia, estoy un poco ... muy preocupado. Patrick Smacchia tiene una buena publicación de blog que describe el objetivo de la nivelación.
Para ser claros: en "ciclo de dependencia" entiendo una referencia circular entre dos espacios de nombres.
Actualmente estoy trabajando en un marco GUI basado en Windows CE para instrumentos integrados, solo piense en la plataforma gráfica de Android pero para instrumentos de muy bajo nivel. El marco es un conjunto único con aproximadamente 50,000 líneas de código (pruebas excluidas). El marco se divide en los siguientes espacios de nombres:
- Navegación principal y subsistema de menú
- Subsistema de pantalla (Presentadores / Vistas / ...)
- Controles / capa de widgets
Hoy pasé medio día tratando de llevar el código a los niveles adecuados [gracias a Resharper, no hay problema en general], pero en todos los casos existen algunos ciclos de dependencia.
Entonces mi pregunta: ¿Cómo sigue estrictamente la regla del "Ciclo sin dependencia"? ¿Es realmente tan importante la nivelación?
fuente
Respuestas:
Recientemente escribí 2 libros blancos, publicados en Simple-Talk sobre el tema de la arquitectura de código .NET (el primer libro trata sobre ensamblados .NET, el segundo sobre espacios de nombres y nivelación):
Particionar su base de código a través de ensamblados .NET y proyectos de Visual Studio
Definición de componentes .NET con espacios de nombres
¡Sí lo es!
Cita del segundo libro blanco:
(...)
fuente
Nunca permito dependencias circulares entre clases o espacios de nombres. En C #, Java y C ++, siempre puede romper una dependencia de clase circular mediante la introducción de una interfaz.
La codificación test-first hace que sea difícil introducir dependencias circulares.
fuente
Siempre es un oficio: debe comprender el costo de las dependencias para comprender por qué deben evitarse las dependencias. Del mismo modo, si comprende el costo de una dependencia, puede decidir mejor si vale la pena en su caso específico.
Por ejemplo, en los videojuegos de consola, a menudo confiamos en dependencias donde se necesitan relaciones cercanas de información, principalmente por razones de rendimiento. Eso está bien siempre que no tengamos que ser tan flexibles como una herramienta de edición, por ejemplo.
Si comprende las restricciones en las que su software tiene que ejecutarse (ya sea hardware, sistema operativo o simplemente diseño (como "la interfaz de usuario más simple que podemos")), debería ser fácil seleccionar qué dependencias no deberían hacerse y cuáles son Okay.
Pero si no tiene una razón buena y clara, evite cualquier dependencia que pueda. El código dependiente es el infierno de la sesión de depuración.
fuente
Cada vez que se discute este tema, los participantes generalmente pierden de vista la distinción entre ciclos de tiempo de construcción y tiempo de ejecución. El primero es lo que John Lakos abordó como "diseño físico", mientras que el segundo es básicamente irrelevante para la discusión (no se obsesione con los ciclos de tiempo de ejecución, como los creados por devoluciones de llamada).
Dicho esto, John Lakos fue muy estricto al eliminar todos los ciclos (tiempo de construcción). Sin embargo, Bob Martin adoptó la actitud de que solo los ciclos entre binarios (por ejemplo, archivos DLL, ejecutables) eran significativos y deberían evitarse; él creía que los ciclos entre clases dentro de un binario no son terriblemente importantes.
Personalmente sostengo el punto de vista de Bob Martin sobre esto. Sin embargo, sigo prestando atención a los ciclos entre clases porque la ausencia de tales ciclos hace que el código sea más fácil de leer y aprender para otros.
Sin embargo, debe señalarse que cualquier código que cree con Visual Studio no es capaz de tener dependencias circulares entre binarios (ya sea código nativo o administrado). Por lo tanto, el problema más grave con los ciclos se ha resuelto para usted. :)
fuente
Casi totalmente, porque los ciclos de dependencia de tipo de compilación son inconvenientes en Haskell e imposibles en Agda y Coq, y esos son los lenguajes que uso habitualmente.
fuente