El diseño de software consiste en decidir cómo se organizará una solución antes y durante su construcción. No se limita a elegir tecnologías ni a dibujar pantallas. Diseñar implica asignar responsabilidades, separar partes del sistema, definir relaciones entre módulos y establecer interfaces claras.
Un buen diseño facilita entender, probar, modificar y mantener el software. Un mal diseño puede hacer que cada cambio sea costoso, riesgoso y difícil de explicar.
En este tema veremos tres ideas centrales del diseño: responsabilidades, módulos e interfaces.
Diseñar software significa tomar decisiones sobre la estructura interna y externa de una solución. Estas decisiones indican qué partes existirán, qué hará cada una, cómo se comunicarán y qué reglas deberán respetar.
Durante el diseño se responden preguntas como:
El análisis se centra en comprender el problema. El diseño se centra en organizar la solución. Ambos están relacionados, pero no son lo mismo.
| Análisis | Diseño |
|---|---|
| Comprende necesidades, reglas y conceptos del negocio. | Decide cómo se estructurará el sistema para responder a esas necesidades. |
| Usa lenguaje del dominio. | Puede usar lenguaje técnico y decisiones de implementación. |
| Pregunta qué ocurre y qué se necesita. | Pregunta cómo se organizará la solución. |
| Ejemplo: un pedido puede estar pendiente, pagado o enviado. | Ejemplo: habrá un módulo de pedidos que validará transiciones de estado. |
Una responsabilidad es algo que una parte del sistema debe saber, hacer o controlar. Asignar responsabilidades correctamente es una de las decisiones más importantes del diseño.
Ejemplos de responsabilidades:
El diseño debe decidir dónde vive cada responsabilidad. Si se ubica en el lugar equivocado, el sistema puede volverse confuso y difícil de cambiar.
Una responsabilidad está bien ubicada cuando la parte que la realiza tiene la información necesaria y es razonable que se encargue de esa tarea.
Por ejemplo, en un sistema de pedidos:
Si una pantalla calcula reglas de negocio complejas, o si el módulo de pagos conoce detalles de presentación, probablemente hay responsabilidades mezcladas.
Un módulo es una parte del sistema que agrupa responsabilidades relacionadas. Puede ser un paquete, componente, servicio, capa, biblioteca, clase o conjunto de archivos, según la tecnología y la arquitectura.
La modularidad busca dividir el sistema para que cada parte tenga un propósito claro. Esto ayuda a:
Los módulos pueden definirse según funcionalidades, responsabilidades técnicas o áreas del dominio.
| Sistema | Módulos posibles |
|---|---|
| Comercio electrónico | Catálogo, carrito, pedidos, pagos, envíos, clientes, promociones. |
| Biblioteca | Catálogo, socios, préstamos, reservas, multas, reportes. |
| Turnos médicos | Pacientes, profesionales, agenda, reservas, notificaciones, administración. |
| Plataforma educativa | Cursos, inscripciones, clases, evaluaciones, certificados, pagos. |
No existe una división única correcta. La división debe responder al dominio, los cambios esperados, el equipo, la tecnología y los atributos de calidad.
Una interfaz define cómo una parte del sistema se comunica con otra. Indica qué operaciones están disponibles, qué datos se reciben, qué resultados se devuelven y qué condiciones deben cumplirse.
Una interfaz puede ser:
Las interfaces son importantes porque permiten que las partes colaboren sin conocer todos los detalles internos de las demás.
Una interfaz funciona como un contrato. Debe dejar claro qué puede esperar quien la usa y qué debe cumplir quien la implementa.
Un buen contrato puede definir:
Cuando una interfaz está mal definida, los módulos quedan acoplados a supuestos informales y los cambios se vuelven riesgosos.
Separar responsabilidades significa evitar que una misma parte del sistema haga demasiadas cosas diferentes. Cuando una parte concentra demasiadas responsabilidades, se vuelve difícil de entender, probar y modificar.
Ejemplo de mezcla de responsabilidades:
Una separación más clara podría distribuir esas tareas:
Una forma común de organizar responsabilidades es separar el sistema en capas. Cada capa tiene un propósito general y se comunica con otras mediante interfaces definidas.
| Capa | Responsabilidad | Ejemplo |
|---|---|---|
| Presentación | Interactuar con usuarios o sistemas externos. | Pantallas, formularios, controladores o endpoints. |
| Aplicación | Coordinar casos de uso y flujo de operaciones. | Crear pedido, cancelar reserva, registrar préstamo. |
| Dominio | Representar reglas y conceptos del negocio. | Pedido, Reserva, Préstamo, políticas de descuento. |
| Infraestructura | Resolver detalles técnicos externos. | Base de datos, correo, archivos, APIs externas. |
No todos los sistemas necesitan estas capas formalmente, pero la idea ayuda a evitar mezclas confusas.
Encapsular significa ocultar detalles internos y exponer solo lo necesario mediante una interfaz. Esto permite cambiar la implementación interna sin afectar a quienes usan el módulo, siempre que el contrato se mantenga.
Ejemplo:
El encapsulamiento reduce dependencias y protege al sistema de cambios innecesarios.
El software cambia. Por eso, el diseño debe considerar qué partes podrían evolucionar. No se trata de anticipar todos los futuros posibles, sino de reconocer puntos de variación razonables.
Preguntas útiles:
Diseñar para el cambio no significa crear abstracciones innecesarias. Significa ubicar responsabilidades para que los cambios esperados no rompan todo el sistema.
En un sistema de biblioteca, podríamos identificar módulos y responsabilidades así:
| Módulo | Responsabilidades | Interfaces posibles |
|---|---|---|
| Catálogo | Gestionar libros, autores, categorías y ejemplares. | Buscar libros, consultar disponibilidad, registrar ejemplar. |
| Socios | Gestionar datos, estado y condiciones de socios. | Consultar socio, validar si puede retirar libros. |
| Préstamos | Registrar préstamos, devoluciones y vencimientos. | Crear préstamo, registrar devolución, consultar vencidos. |
| Reservas | Gestionar solicitudes de reserva y disponibilidad futura. | Crear reserva, cancelar reserva, notificar disponibilidad. |
| Notificaciones | Enviar avisos a socios. | Enviar aviso de vencimiento o confirmación. |
En una tienda en línea, una compra puede involucrar varios módulos:
Si estas responsabilidades están mezcladas en un único bloque, cualquier cambio será difícil. Si están separadas con interfaces claras, el sistema será más comprensible y mantenible.
Al diseñar software suelen aparecer errores como:
Algunas prácticas útiles para diseñar mejor son:
Diseñar software es organizar responsabilidades, módulos e interfaces para que el sistema pueda construirse, comprenderse y modificarse de forma razonable. Un buen diseño no se nota solo cuando el sistema funciona, sino cuando puede cambiar sin volverse inmanejable.
Para quien comienza, la idea principal es esta: el diseño convierte un problema entendido en una solución organizada, donde cada parte tiene un propósito claro y se comunica mediante acuerdos definidos.
En el próximo tema veremos principios básicos de diseño como cohesión, acoplamiento y abstracción, que ayudan a evaluar si esa organización es adecuada.