Programación modular es un paradigma de desarrollo de software que consiste en
dividir un programa grande y complejo en partes más pequeñas, independientes y
manejables llamadas módulos. Cada módulo se enfoca en una funcionalidad
específica y se diseña para ser reutilizable, fácil de mantener y probar por
separado.
Caracteristicas clave:
Encapsulación: Cada módulo oculta sus detalles internos y expone solo una
interfaz clara.
Cohesión alta: Un módulo realiza una única tarea o un conjunto relacionado de
funciones.
Bajo acoplamiento: Los módulos dependen mínimamente entre sí, comunicándose
mediante interfaces definidas.
Reutilización: Módulos bien diseñados pueden usarse en distintos proyectos.
Diseños descendientes
El diseño descendente es una metodología de análisis y desarrollo que aborda
sistemas complejos descomponiéndolos jerárquicamente desde el nivel más
abstracto (general) hacia los niveles más concretos (detallados).
¿Qué es un Módulo?
Un módulo es una unidad de código autocontenida y reutilizable que agrupa
elementos relacionados (funciones, clases, variables, constantes) para realizar
una tarea específica dentro de un programa. Actúa como un bloque de
construcción en la programación modular.
Características esenciales:
1. Encapsulación: Oculta los detalles internos de implementación, exponiendo solo lo
necesario a través de una interfaz pública.
2. Responsabilidad única: Se diseña para cumplir una función concreta y bien
definida.
3. Independencia relativa: Puede funcionar y probarse en gran medida por separado
del sistema completo.
4. Interfaz definida: Tiene puntos claros de comunicación (parámetros de entrada y
valores de retorno).
Ejemplos concretos:
En Python: Un archivo .py que contiene funciones relacionadas
(ej: [Link], [Link])
En JavaScript: Un archivo .js que exporta funciones/objetos específicos
En aplicaciones empresariales:
o Módulo de autenticación de usuarios
o Módulo de cálculo de nóminas
o Módulo de generación de reportes
Beneficios prácticos:
Organización: Divide sistemas complejos en partes comprensibles
Mantenibilidad: Permite modificar un módulo sin afectar otros
Reutilización: El mismo módulo puede usarse en múltiples proyectos
Colaboración: Diferentes programadores pueden trabajar en módulos
distintos simultáneamente
Pruebas unitarias: Facilita testear funcionalidades aisladas
¿Qué es un diseño descendiente con pseudocódigo?
DEFINICIÓN CONCISA:
El diseño descendente es una metodología de desarrollo que aborda problemas
complejos dividiéndolos en partes más pequeñas y simples, comenzando desde el
nivel más general hacia los detalles específicos.
ANALOGÍA CLARA:
Imagina planificar un viaje:
1. Nivel 1: Decidir el destino principal (Ej: "Viajar a Europa")
2. Nivel 2: Dividir en etapas ("Transporte", "Alojamiento", "Actividades")
3. Nivel 3: Detallar cada etapa ("Vuelo: aerolínea, horario, precio")
4. Nivel 4: Especificar acciones ("Reservar en línea, imprimir pases")
Ejemplo en pseudocódigo
Algoritmo hola_mundo
Definir num1, num2, resultado Como Real
Definir operación Como Carácter
Escribir "CALCULADORA CIENTÍFICA"
Escribir "Ingrese primer número: "
Leer num1
Escribir "Ingrese operación (+, -, *, /, ^, r): "
Leer operación
Si operación <> 'r' Entonces
Escribir "Ingrese segundo número: "
Leer num2
FinAlgoritmo
Proceso de modularización o segmentación
La modularización es el proceso sistemático de dividir un sistema complejo en
componentes más pequeños, autónomos y especializados llamados módulos,
cada uno con una responsabilidad bien definida y limitada.
Modularizacion funcional
La modularización funcional es un paradigma de diseño que organiza un
sistema en módulos basados exclusivamente en funciones o tareas
específicas que deben realizarse, donde cada módulo corresponde a una
operación discreta y autónoma dentro del proceso general.
PRINCIPIOS ESENCIALES
1. CORRESPONDENCIA FUNCIÓN-MÓDULO
Cada función identificada en el análisis de requisitos se traduce directamente en
un módulo independiente. La relación es biunívoca: una función = un módulo.
2. AUTONOMÍA OPERACIONAL
Cada módulo funcional debe poder ejecutarse y probarse de manera aislada,
requiriendo solo entradas definidas y produciendo salidas esperadas.
3. ESPECIALIZACIÓN ESTRICTA
Un módulo realiza una y solo una función claramente definida, evitando la
multifuncionalidad que reduce la cohesión.
4. JERARQUÍA FUNCIONAL
Las funciones se organizan en árboles donde funciones complejas se
descomponen en subfunciones más simples, reflejando esta estructura en la
jerarquía modular.
Cohesión y acoplamiento
CONCEPTO FUNDAMENTAL
Cohesión y Acoplamiento son los dos principios cardinales del diseño modular que
determinan la calidad, mantenibilidad y escalabilidad de un sistema software.
Representan fuerzas opuestas que Deben equilibrarse estratégicamente.
COHESIÓN
DEFINICIÓN
Grado en que los elementos internos de un módulo están relacionados entre sí y
trabajan juntos para realizar una única tarea bien definida.
ANALOGÍA: COHESIÓN EN EQUIPOS
Alta cohesión: Un equipo de cirugía donde cada miembro tiene un rol específico
pero todos colaboran en una sola operación
Baja cohesión: Un grupo donde cada persona hace tareas no relacionadas (uno
cocina, otro repara autos, otro enseña matemáticas)
ESCALA DE COHESIÓN (DE MEJOR A PEOR)
1. COHESIÓN FUNCIONAL (ÓPTIMA)
Todos los elementos contribuyen a una única tarea bien definida
El módulo tiene un propósito único y claro
Ejemplo: CalcularImpuesto(), ValidarEmail(), EncriptarDatos()
2. COHESIÓN SECUENCIAL
Elementos están relacionados porque la salida de uno es entrada del siguiente
Forman una cadena de procesamiento
Ejemplo: LeerDatos() → ProcesarDatos() → GuardarResultados()
3. COHESIÓN COMUNICACIONAL
Elementos operan sobre los mismos datos/conjunto de datos
No hay flujo secuencial pero comparten información
Ejemplo: CalcularPromedio(), CalcularMaximo(), CalcularMinimo() sobre el mismo
array
4. COHESIÓN PROCEDIMENTAL
Elementos están relacionados porque deben ejecutarse en un orden específico
Determinado por flujo de control más que por datos
Ejemplo: InicializarSistema() → CargarConfig() → EstablecerConexiones()
5. COHESIÓN TEMPORAL
Elementos se agrupan porque se ejecutan en el mismo período temporal
Relación basada en momento de ejecución
Ejemplo: InicioSistema() que llama a múltiples inicializaciones no relacionadas
6. COHESIÓN LÓGICA
Elementos se agrupan porque lógicamente pertenecen a la misma categoría
Relación conceptual pero no operacional
Ejemplo: ManejoErrores() que incluye logging, notificación, recuperación
7. COHESIÓN COINCIDENTAL (PEOR)
Elementos no tienen ninguna relación significativa
Agrupación arbitraria o por conveniencia
Ejemplo: Utilidades() con funciones completamente diversas
PRINCIPIO: MÁXIMA COHESIÓN
"Un módulo debe hacer una cosa, hacerla bien, y hacerla completamente."
ACOPLAMIENTO
DEFINICIÓN
Grado de interdependencia entre módulos. Mide cuánto un módulo depende de los
detalles internos de otro módulo.
ANALOGÍA: ACOPLAMIENTO EN CONSTRUCCIÓN
Bajo acoplamiento: Bloques LEGO que se conectan mediante interfaces estándar
Alto acoplamiento: Piezas de un motor fusionadas entre sí, imposibles de separar
ESCALA DE ACOPLAMIENTO (DE MEJOR A PEOR)
1. ACOPLAMIENTO DE DATOS (ÓPTIMO)
Módulos se comunican solo mediante parámetros simples
Cada dato es independiente
Ejemplo: CalcularArea(ancho, alto)
2. ACOPLAMIENTO DE ESTAMPILLA
Módulos comparten una estructura de datos compuesta
Conocen el formato pero no modifican internamente
Ejemplo: ProcesarFactura(Factura factura)
3. ACOPLAMIENTO DE CONTROL
Un módulo controla la lógica de otro
Pasa información de control (flags, switches)
Ejemplo: Procesar(modo="rápido")
4. ACOPLAMIENTO EXTERNO
Módulos comparten un formato o protocolo externo
Dependen de estándares externos
Ejemplo: Ambos módulos escriben en el mismo formato de archivo XML
5. ACOPLAMIENTO COMÚN/GLOBAL
Módulos comparten variables o datos globales
Cambios afectan múltiples módulos
Ejemplo: Variable global configuracionSistema
6. ACOPLAMIENTO DE CONTENIDO (PEOR)
Un módulo modifica directamente los internos de otro
Rompe encapsulamiento por completo
Ejemplo: Módulo A modifica variables privadas del Módulo B
PRINCIPIO: MÍNIMO ACOPLAMIENTO
"Los módulos deben interactuar lo menos posible, y cuando lo hagan, debe ser a
través de interfaces bien definidas."
Alcance de las variables
El alcance (scope) de una variable define su visibilidad y vida útil dentro del
código: dónde puede ser accedida, modificada y cuánto tiempo permanece en
memoria. Determina la accesibilidad de una variable en diferentes partes del
programa.
Tipos de Alcance Principales:
1. Alcance Local (Bloque)
Declarada dentro de una función, procedimiento o bloque {}
Solo accesible dentro de ese bloque específico
Se crea al entrar al bloque y se destruye al salir
Ejemplo: Variables dentro de un bucle for, condicional if
2. Alcance Global
Declarada fuera de todas las funciones
Accesible desde cualquier parte del programa
Existe durante toda la ejecución del programa
Riesgo: Puede ser modificada desde cualquier lugar (efectos colaterales)
3. Alcance de Función/Parámetros
Parámetros formales de una función
Visibles solo dentro de esa función
Reciben valores de los argumentos actuales
Ejemplo: function suma(a, b) - a y b son alcance de función
Funciones definidas por el usuario
Concepto Fundamental
Las funciones definidas por el usuario son bloques de código reutilizables creados
por el programador para realizar tareas específicas, organizar la lógica y evitar la
repetición de código.
Componentes Esenciales:
1. Declaración/Definición
Nombre: Identificador único que describe su propósito
Parámetros formales: Variables que reciben valores de entrada
Cuerpo: Bloque de instrucciones que ejecuta la función
Valor de retorno: Resultado que devuelve (opcional en algunos casos)
2. Invocación/Llamada
Uso de la función mediante su nombre
Paso de argumentos reales a los parámetros formales
Recepción del valor retornado (si aplica)
3. Prototipo/Firma
Especificación formal de la función: nombre, parámetros, tipo de retorno
En algunos lenguajes se declara antes de la implementación
Tipos de Funciones por Retorno:
1. Funciones con Retorno
Devuelven un valor usando return o retornar
Pueden usarse en expresiones (asignaciones, cálculos)
Ejemplo: funcion CalcularIVA(monto)
2. Procedimientos/Subrutinas
No retornan valor (void)
Ejecutan acciones o efectos secundarios
Ejemplo: procedimiento ImprimirReporte()
3. Funciones Puras
Mismo input → siempre mismo output
Sin efectos secundarios (no modifican estado externo)
Ejemplo: funcion ElevarAlCuadrado(numero)
4. Funciones con Efectos Secundarios
Modifican variables globales, archivos, bases de datos
Cambian el estado del sistema
Ejemplo: funcion GuardarEnBaseDatos(registro)
Ventajas de la modularidad
1. REDUCCIÓN DE COMPLEJIDAD
Divide problemas grandes en partes manejables más pequeñas
Cada módulo aborda una sola responsabilidad específica
Facilita la comprensión al reducir la carga cognitiva
Permite enfocarse en un aspecto a la vez sin abrumarse
2. REUTILIZACIÓN DE CÓDIGO
Módulos bien diseñados pueden usarse en múltiples proyectos
Evita la duplicación de código (principio DRY - Don't Repeat Yourself)
Crea bibliotecas de componentes probados y confiables
Reduce tiempo de desarrollo en proyectos futuros
3. FACILIDAD DE MANTENIMIENTO
Los errores se localizan y corrigen en módulos específicos
Cambios y actualizaciones afectan áreas limitadas del sistema
Simplifica la depuración al aislar problemas
Permite evolucionar el sistema por partes, no como un todo
4. DESARROLLO EN PARALELO
Múltiples equipos o desarrolladores pueden trabajar simultáneamente
Cada grupo se especializa en módulos diferentes
Acelera el tiempo total de desarrollo
Facilita la gestión de proyectos complejos
5. TESTEO Y VERIFICACIÓN
Cada módulo puede probarse independientemente (pruebas unitarias)
Simplifica la creación de casos de prueba específicos
Aísla problemas durante la integración
Facilita la automatización de pruebas
6. ESCALABILIDAD Y FLEXIBILIDAD
Nuevas funcionalidades se añaden como módulos adicionales
Permite reemplazar módulos sin afectar el sistema completo
Facilita la adaptación a cambios en requisitos
Soporta crecimiento gradual y controlado
7. ENCAPSULAMIENTO Y ABSTRACCIÓN
Oculta detalles de implementación complejos
Expone solo interfaces claras y necesarias
Reduce acoplamiento entre componentes
Protege la integridad de los datos internos
8. MEJORA LA CALIDAD DEL CÓDIGO
Fomenta coherencia y estandarización
Promueve mejores prácticas de diseño
Facilita revisiones de código más efectivas
Reduce la probabilidad de errores por interferencia
9. DOCUMENTACIÓN NATURAL
La estructura modular documenta la arquitectura del sistema
Cada módulo tiene responsabilidades claramente definidas
Facilita el onboarding de nuevos desarrolladores
Crea una organización lógica y predecible
10. GESTIÓN DE RIESGOS
Fallos en un módulo no colapsan el sistema completo
Permite implementar redundancia en componentes críticos
Facilita estrategias de rollback específicas
Aísla problemas de seguridad a áreas confinadas
11. OPTIMIZACIÓN SELECTIVA
Módulos críticos para rendimiento pueden optimizarse individualmente
Permite diferentes estrategias de optimización por componente
Facilita el perfilado y análisis de rendimiento por secciones
Recursos pueden asignarse donde más se necesitan
12. PORTABILIDAD Y DISTRIBUCIÓN
Módulos pueden distribuirse como paquetes independientes
Facilita la creación de APIs y microservicios
Permite reutilización entre diferentes plataformas
Soporta arquitecturas distribuidas y en la nube
13. ESPECIALIZACIÓN DEL EQUIPO
Desarrolladores pueden especializarse en dominios específicos
Facilita la mentoría y transferencia de conocimiento
Crea expertos en áreas técnicas particulares
Mejora la productividad a largo plazo
14. GESTIÓN DE VERSIONES
Cada módulo puede versionarse independientemente
Facilita el control de cambios y historial
Permite compatibilidad con múltiples versiones
Simplifica las actualizaciones graduales
15. REDUCCIÓN DE COSTOS
Disminuye tiempo de desarrollo por reutilización
Reduce costos de mantenimiento y soporte
Minimiza riesgo de errores costosos
Optimiza inversión en pruebas y calidad