Diagramas estructurados · Análisis de transformación y transacción · Cohesión y acoplamiento
| Concepto | Definición |
|---|---|
| Módulo | Unidad lógica y física del software con un nombre, función bien definida, entradas y salidas. Puede ser un procedimiento, función, subrutina, etc. |
| Descomposición funcional | Proceso de dividir el sistema en subsistemas y módulos de menor tamaño y complejidad |
| Abstracción | Capacidad de tratar un módulo como una caja negra, sin necesidad de conocer su implementación interna |
| Independencia funcional | Propiedad deseable: cada módulo realiza una función concreta y bien delimitada con mínima interacción con otros módulos |
| Ocultación de información | Principio de Parnas: los detalles de implementación de un módulo no deben ser visibles desde fuera |
Los dos criterios principales para evaluar la calidad de la descomposición modular son:
Mide el grado de relación entre los elementos internos de un módulo. A mayor cohesión, mejor diseño.
Mide la dependencia entre módulos. A menor acoplamiento, más fácil de mantener y reutilizar.
| Elemento | Símbolo / Representación | Significado |
|---|---|---|
| Módulo | Rectángulo con nombre | Unidad de software (función, procedimiento). El nombre describe su función |
| Módulo de librería | Rectángulo con franja inferior doble | Módulo reutilizable, compartido por varios módulos superiores |
| Llamada (invocación) | Flecha sólida de padre a hijo | El módulo padre invoca al módulo hijo |
| Datos (parámetros de datos) | Flecha con círculo relleno (●) | Dato de entrada/salida que se transmite entre módulos |
| Flags (indicadores de control) | Flecha con círculo vacío (○) | Parámetro de control (boolean, código de estado) que altera el flujo |
| Bucle (iteración) | Arco sobre las llamadas a módulos hijos | El módulo padre llama repetidamente a uno o varios hijos |
| Selección (alternativa) | Rombo sobre las llamadas alternativas | El módulo padre llama a uno u otro módulo hijo según condición |
Estructura típica de un programa de gestión de pedidos:
Jerarquía de módulos · Las flechas representan llamadas del módulo padre al hijo
| Propiedad | Descripción | Valor deseable |
|---|---|---|
| Fan-out (abanico de salida) | Número de módulos a los que un módulo llama directamente | Entre 3 y 9. Fan-out alto → módulo sobrecargado |
| Fan-in (abanico de entrada) | Número de módulos que llaman a un módulo dado | Fan-in alto es bueno → módulo reutilizable |
| Profundidad (depth) | Número de niveles de la jerarquía | Ni demasiado plana (fan-out muy alto) ni demasiado profunda (difícil seguir) |
| Anchura (width) | Número máximo de módulos en un mismo nivel | Equilibrada |
| Aspecto | Yourdon-Constantine (SC) | DeMarco (DFD → SC) |
|---|---|---|
| Punto de partida | Diseño directo de la estructura modular | Derivación a partir del Diagrama de Flujo de Datos (DFD) |
| Flujos de datos | Marcados explícitamente en el SC | Se mapean desde el DFD usando análisis de transformación/transacción |
| Uso principal | Diseño general de la arquitectura | Diseño en contexto de metodología estructurada completa |
Un DFD exhibe flujo de transformación cuando se puede identificar claramente:
| Parte del DFD | Descripción | En el SC derivado |
|---|---|---|
| Flujo de entrada (afluente de entrada) | Datos que fluyen desde las fuentes externas hacia el interior del sistema, pasando por transformaciones de entrada | Se convierte en módulos de entrada |
| Transformación central (centro de transformación) | El "núcleo" del sistema: los procesos que realizan la función principal, alejados de la frontera de entrada/salida | Se convierte en módulos de proceso central |
| Flujo de salida (afluente de salida) | Datos que fluyen desde el centro hacia los destinos externos, pasando por transformaciones de salida | Se convierte en módulos de salida |
Partir del DFD del sistema con sus procesos, flujos, almacenes y entidades externas correctamente definidos.
Asegurarse de que el DFD sea una representación correcta del sistema a nivel de diseño. Añadir detalles si son necesarios.
Si el DFD tiene una transformación central dominante → análisis de transformación. Si hay un punto de despacho a varias corrientes → análisis de transacción.
Identificar el límite entre los flujos de entrada y el centro de transformación, y entre el centro y los flujos de salida. Es el paso más subjetivo y crítico.
Crear un módulo de control principal con tres ramas: módulo coordinador de entrada, módulo de transformación central y módulo coordinador de salida.
Desarrollar cada rama siguiendo la estructura del DFD, creando submódulos para cada proceso del DFD correspondiente.
Aplicar heurísticas de diseño para mejorar la cohesión, reducir el acoplamiento y ajustar el fan-out de cada módulo.
Estructura tipo del análisis de transformación · 3 ramas principales bajo el módulo coordinador
| Característica | Flujo de Transformación | Flujo de Transacción |
|---|---|---|
| Patrón | Un flujo lineal: entrada → proceso central → salida | Un punto de despacho que distribuye a varias corrientes alternativas |
| Número de caminos | Generalmente uno principal | Varios caminos alternativos (uno por tipo de transacción) |
| Analogía | Cadena de montaje (entrada, proceso, salida) | Conmutador telefónico o menú de opciones |
| Ejemplo típico | Cálculo de nómina | Menú bancario (consulta / transferencia / ingreso / retirada) |
Localizar el proceso que actúa como distribuidor: recibe una entrada y la dirige hacia distintas corrientes de procesamiento según su tipo.
Módulo de alto nivel que acepta la entrada y decide qué corriente de acción activar. Equivale al dispatcher o controlador.
Cada tipo de transacción (cada camino en el DFD) se convierte en un módulo hijo del coordinador.
Cada corriente puede contener a su vez un flujo de transformación o de transacción, que se descompone aplicando la técnica correspondiente recursivamente.
Aplicar heurísticas para mejorar cohesión, reducir acoplamiento y ajustar proporciones del árbol.
Estructura tipo CRUD derivada por análisis de transacción · Un módulo por cada tipo de transacción
| Aspecto | Análisis de Transformación | Análisis de Transacción |
|---|---|---|
| Patrón de flujo | Lineal: entrada → centro → salida | Ramificado: centro distribuye a corrientes alternativas |
| Estructura resultante | 3 ramas principales (entrada, proceso, salida) | N ramas (una por tipo de transacción) |
| Módulo dominante | Módulo de transformación central | Módulo dispatcher/controlador |
| Identificación | Se identifica la "frontera" entre flujo físico y lógico | Se identifica el punto de despacho en el DFD |
| Aplicación típica | Sistemas batch, procesos de cálculo, transformaciones de datos | Sistemas de menú, CRUD, sistemas de comandos interactivos |
Se definen 7 niveles, ordenados de peor a mejor:
| # | Nivel | Calidad | Descripción | Ejemplo |
|---|---|---|---|---|
| 1 | Cohesión Coincidental | Muy mala | Los elementos del módulo no tienen ninguna relación entre sí. Son un conjunto arbitrario de sentencias agrupadas por conveniencia | Un módulo "Miscelánea" que imprime un mensaje, calcula el IVA y cierra un fichero |
| 2 | Cohesión Lógica | Mala | Los elementos realizan funciones de la misma categoría lógica, pero se selecciona cuál ejecutar mediante un parámetro de control. La interfaz es engañosa | Módulo de "Gestión de E/S" que según un flag lee, escribe o cierra un fichero |
| 3 | Cohesión Temporal | Mala | Los elementos se agrupan porque se ejecutan en el mismo momento (ej.: inicialización al arrancar el sistema), no porque estén funcionalmente relacionados | Módulo InicializarSistema() que abre BD, inicializa variables y carga tablas maestras |
| 4 | Cohesión Procedural | Media | Los elementos están relacionados porque siguen un flujo de control secuencial (uno después de otro), aunque no estén funcionalmente relacionados. Depende del orden de ejecución | Módulo que verifica permisos, luego lee el fichero, luego actualiza el log |
| 5 | Cohesión Comunicacional | Media-alta | Los elementos operan sobre el mismo conjunto de datos de entrada o producen la misma salida. Están relacionados por los datos que manejan | Módulo que calcula la media, el máximo y el mínimo del mismo vector de datos |
| 6 | Cohesión Secuencial | Buena | La salida de un elemento es la entrada del siguiente. Los elementos están relacionados porque forman una cadena de transformación de datos (pipeline) | Módulo que lee un registro, lo valida y lo formatea: la salida de cada paso es la entrada del siguiente |
| 7 | Cohesión Funcional | Óptima | Todos los elementos contribuyen a realizar una única función bien definida. Es el nivel de cohesión ideal: el módulo hace una sola cosa y la hace bien (principio de responsabilidad única) | calcularSeno(x), ordenarLista(lista), validarNIF(nif) |
Técnica práctica de Myers: describir la función del módulo con una sola frase y analizarla:
| Si la descripción contiene… | Nivel de cohesión probable |
|---|---|
| Una sola función específica (ej.: "Calcula el IVA de una factura") | Funcional ✅ |
| "Y además…" (más de una función en la descripción) | Secuencial o menor ⚠️ |
| "En el momento de…" o "al inicio / al final" | Temporal ❌ |
| "Todo tipo de…" o "varios tipos de…" | Lógica ❌ |
| No hay relación clara entre las cosas que hace | Coincidental ❌ |
Se definen 6 niveles, ordenados de mayor a menor acoplamiento (de peor a mejor):
| # | Nivel | Gravedad | Descripción | Ejemplo |
|---|---|---|---|---|
| 1 | Acoplamiento de Contenido | Crítico | Un módulo accede o modifica directamente el interior de otro (código, datos internos). Solo posible en ensamblador o C sin protección | Módulo A modifica una variable local de módulo B sin pasar por su interfaz |
| 2 | Acoplamiento Común | Muy malo | Dos o más módulos hacen referencia al mismo dato global (variable global, área común de memoria). Un cambio en ese dato afecta a todos | Variables globales compartidas entre módulos; áreas COMMON en COBOL/Fortran |
| 3 | Acoplamiento Externo | Malo | Los módulos comparten un formato de datos externo, protocolo de comunicación o dispositivo externo. Similar al común pero referido a datos externos al programa | Dos módulos que leen y escriben el mismo formato de fichero externo directamente |
| 4 | Acoplamiento de Control | Medio | Un módulo pasa a otro un indicador de control (flag) que altera su flujo interno. El módulo llamante sabe cómo funciona el módulo llamado | Llamada procesarRegistro(registro, tipoOperacion) donde tipoOperacion decide qué hace el módulo internamente |
| 5 | Acoplamiento de Marca (Stamp) | Aceptable | Los módulos comparten una estructura de datos compuesta (registro, objeto), pero el módulo receptor solo usa parte de ella. Se transmite más información de la necesaria | Pasar un registro completo de cliente a un módulo que solo necesita el NIF |
| 6 | Acoplamiento de Datos | Óptimo | Los módulos se comunican únicamente mediante parámetros simples (datos elementales) que son exactamente los necesarios. Es el nivel de acoplamiento ideal | calcularIVA(baseImponible, tipoIVA) → recibe solo lo que necesita, devuelve solo el resultado |
| Factor | Menor acoplamiento | Mayor acoplamiento |
|---|---|---|
| Tipo de conexión | Llamada por interfaz definida (parámetros) | Acceso directo a datos internos |
| Tipo de datos transmitidos | Datos elementales necesarios | Estructuras completas, flags de control |
| Número de parámetros | Los mínimos necesarios | Muchos parámetros, estructuras complejas |
| Uso de globales | Sin variables globales | Datos globales compartidos |
| Conocimiento del interior | Módulo tratado como caja negra | Un módulo conoce el funcionamiento interno del otro |
Rompe la abstracción y la ocultación de información. Imposible probar un módulo independientemente. Cualquier refactorización interna puede romper otros módulos. Prácticamente eliminado en lenguajes modernos.
Dificulta el razonamiento sobre el comportamiento del programa. Introduce efectos secundarios inesperados. Hace imposible la reutilización del módulo en otro contexto. Principal fuente de bugs en sistemas grandes.
| Métrica | Objetivo | Nivel peor | Nivel mejor | Consecuencia de un mal valor |
|---|---|---|---|---|
| Cohesión | Maximizar | Coincidental (1) | Funcional (7) | Módulos difíciles de entender, probar y reutilizar |
| Acoplamiento | Minimizar | De contenido (más alto) | De datos (más bajo) | Cambios en cascada, dificultad para mantenimiento |
| # | Heurística | Descripción práctica |
|---|---|---|
| H1 | Evaluar la primera iteración | La primera estructura derivada del DFD es un punto de partida, no el diseño final. Siempre se refina |
| H2 | Implosión y explosión | Si un módulo tiene fan-out muy alto (>7) → implosionar (añadir un módulo intermedio). Si un módulo tiene una sola función trivial → explotar (integrarlo en el padre) |
| H3 | Minimizar las interfaces | Reducir el número y complejidad de los parámetros entre módulos. Pasar solo lo necesario |
| H4 | Limitar el tamaño | Un módulo no debería superar 30-50 líneas de código. Si es mayor, probablemente hace demasiadas cosas |
| H5 | Evitar el acoplamiento de control | Si un módulo pasa flags al hijo, considerar si no sería mejor dividirlo en dos módulos con nombres distintos |
| H6 | Módulos con función única y clara | El nombre del módulo debe describir completamente lo que hace. Si no es posible en pocas palabras, el módulo tiene baja cohesión |
| H7 | Reutilización | Identificar funciones comunes y extraerlas como módulos de librería (fan-in alto) para maximizar la reutilización |
| Combinación | Impacto en mantenibilidad | Impacto en reutilización | Impacto en pruebas |
|---|---|---|---|
| Alta cohesión + bajo acoplamiento ✅ | Excelente: cambios localizados | Excelente: módulos independientes | Excelente: prueba unitaria sencilla |
| Alta cohesión + alto acoplamiento ⚠️ | Regular: cambios se propagan | Mala: dependencias externas | Difícil: hay que montar el contexto |
| Baja cohesión + bajo acoplamiento ⚠️ | Regular: módulo confuso internamente | Limitada: función no clara | Difícil: comportamiento impredecible |
| Baja cohesión + alto acoplamiento ❌ | Pésima: cambios en cascada en módulos confusos | Nula | Muy difícil o imposible de aislar |
| Concepto | Autor/Origen | Palabras clave |
|---|---|---|
| Diseño estructurado | Yourdon, Constantine (1979) | Módulo, fan-in, fan-out, jerarquía, independencia funcional |
| Diagrama estructurado (SC) | Constantine & Yourdon | Rectángulo, flecha, parámetro, flag, bucle, selección |
| Análisis de transformación | DeMarco, Yourdon | DFD, flujo de entrada, transformación central, flujo de salida |
| Análisis de transacción | DeMarco, Yourdon | Centro de transacción, dispatcher, corrientes de acción |
| Cohesión | Constantine & Yourdon, Myers | 7 niveles, funcional (óptima), coincidental (peor), responsabilidad única |
| Acoplamiento | Constantine & Yourdon | 6 niveles, datos (óptimo), contenido (peor), variables globales, flags |