Saber Pro Diseño de Software cheat sheet
Saber Pro Diseño de Software · Keep the key ideas within reach.
Diseño de Software
Principios SOLID: S (una clase, una razón de cambio), O (extensible sin modificar código estable), L (subtipo sustituible sin romper contratos), I (interfaces pequeñas y específicas), D (depender de abstracciones, no de concreciones).
Acoplamiento vs. cohesión: el diseño busca bajo acoplamiento entre módulos y alta cohesión dentro de cada módulo; métricas asociadas: fan-in/fan-out y LCOM.
Patrones creacionales: Singleton (instancia única con constructor privado), Factory Method (delega la creación en subclases), Abstract Factory (familias de productos), Builder (construcción paso a paso), Prototype (clonación).
Patrones estructurales: Adapter (convierte interfaces), Decorator (añade responsabilidades en tiempo de ejecución), Facade (interfaz simplificada), Proxy (intermediario de control), Composite (jerarquías parte-todo), Bridge (separa abstracción de implementación).
Patrones de comportamiento: Observer (notificación uno-a-muchos), Strategy (algoritmos intercambiables), Command (encapsula peticiones), Template Method (esqueleto con pasos variables), State (comportamiento según estado), Chain of Responsibility (cadena de manejadores).
Cohesión de patrones GRASP: Information Expert (asignar responsabilidad a quien tiene los datos), Creator, Controller, Low Coupling, High Cohesion, Polymorphism, Pure Fabrication, Indirection, Protected Variations.
Regla de sustitución de Liskov: si S es subtipo de T, objetos de T deben poder reemplazarse por S sin alterar la corrección; precondiciones no se refuerzan y postcondiciones no se debilitan en el subtipo.
Ley de Demeter: un objeto solo debe invocar métodos de sí mismo, de sus parámetros, de objetos que crea y de sus componentes directos; evita cadenas como a.getB().getC().doIt().
Deuda técnica: diferencia entre el costo de mantener el diseño actual y el de un diseño ideal; se registra y prioriza, no se ignora; el refactor preserva comportamiento externo y se respalda con pruebas automatizadas.
Arquitectura y Estilos Arquitectónicos
Estilos arquitectónicos: capas (dependencias descendentes), cliente-servidor, pipes and filters (transformación secuencial), event-driven (publicador/suscriptor), microkernel (núcleo + plugins), microservicios (servicios autónomos por dominio).
Atributos de calidad ISO/IEC 25010 relevantes al diseño: mantenibilidad (modularidad, reusabilidad, analizabilidad), fiabilidad, eficiencia de desempeño, seguridad, compatibilidad, usabilidad y portabilidad.
Tácticas de arquitectura: modularidad, encapsulamiento, separación de intereses, abstracción, acoplamiento débil, cohesión alta, ocultamiento de información (Parnas) y separación interfaz-implementación.
Vista 4+1 de Kruchten: lógica, de procesos, de desarrollo, física y de escenarios; cada vista responde a un interés distinto de los stakeholders.
C4 model: Contexto, Contenedores, Componentes y Código; útil para comunicar arquitectura a distintos niveles de audiencia.
ADRs (Architecture Decision Records): documentan contexto, decisión y consecuencias de una elección arquitectónica; son inmutables y se versionan junto al código.
Microservicios: base de datos por servicio, comunicación por API/eventos, consistencia eventual y patrón Saga para transacciones distribuidas; riesgo de latencia y complejidad operativa.
Monolito modular: una sola unidad de despliegue con módulos de límites claros; menor costo operativo que microservicios y adecuado cuando el dominio aún no está bien delimitado.
Modelado y UML
Diagramas UML 2.x de estructura: clases, objetos, componentes, despliegue, paquetes, perfil y estructura compuesta; de comportamiento: casos de uso, actividad, máquina de estados, secuencia, comunicación, tiempos e interacción global.
Relaciones UML: dependencia (línea discontinua), asociación, agregación (rombo hueco, ciclo de vida independiente), composición (rombo relleno, parte muere con el todo), generalización y realización (línea discontinua con triángulo hueco).
Multiplicidad en asociaciones: 1, 0..1, , 1.., 0..*; se ubica en el extremo opuesto a la clase que se describe.
Diagrama de secuencia: línea de vida, activación (barra), mensajes síncronos (punta rellena), asíncronos (punta abierta), retorno (línea discontinua) y fragmentos combined (alt, opt, loop, par).
Diagrama de casos de uso: actor (persona o sistema externo), caso de uso (elipse), include (comportamiento obligatorio reutilizado) y extend (comportamiento opcional en un punto de extensión).
Diagrama de clases: clase con compartimentos de nombre, atributos y operaciones; visibilidad + público, - privado, # protegido, ~ paquete; el estereotipo se escribe entre «» .
Máquina de estados: estado inicial (círculo relleno), final (círculo con anillo), transiciones etiquetadas evento[guarda]/acción y estados compuestos con regiones.
Modelado ágil: el diagrama es un medio de comunicación, no un entregable; se prefieren bocetos de pizarra y solo se documenta lo que reduce riesgo.
Calidad, Pruebas y Refactorización
Pirámide de pruebas: muchas unitarias (rápidas, aisladas), menos de integración y pocas de extremo a extremo; la base debe ser automatizable y determinista.
TDD: ciclo rojo-verde-refactor; se escribe primero la prueba que falla, luego el código mínimo que la hace pasar y después se refactoriza sin cambiar comportamiento.
Cobertura: cobertura de sentencias, de ramas y de condiciones; 100 % de cobertura no implica ausencia de defectos, solo ejecución de líneas o decisiones.
Pruebas de caja negra: partición de equivalencia, análisis de valores límite, tablas de decisión y transición de estados; caja blanca: cobertura de caminos y complejidad ciclomática.
Complejidad ciclomática de McCabe: V(G) = E − N + 2P, o V(G) = número de regiones del grafo, o decisiones + 1; indica el número mínimo de caminos independientes a probar.
Refactorizaciones seguras: extraer método, extraer clase, renombrar, mover método/campo, introducir objeto parámetro, reemplazar condicional por polimorfismo; requieren pruebas de regresión verdes.
Code smells: código duplicado, método largo, clase grande, envidia de características, lista de parámetros larga, obsesión por primitivos, sentencias switch repetidas, acoplamiento excesivo.
Pruebas de regresión: garantizan que un cambio no rompe funcionalidad existente; se automatizan y se ejecutan en cada integración continua.
Gestión y Proceso de Diseño
Metodologías: cascada (fases secuenciales, cambios costosos), iterativa/incremental (entregas cortas) y ágil (Scrum, Kanban, XP); el diseño se adapta al ciclo elegido.
Scrum: roles Product Owner, Scrum Master y Developers; artefactos Product Backlog, Sprint Backlog e Incremento; eventos Sprint Planning, Daily, Review y Retrospectiva.
Estimación: story points con Planning Poker, tallas de camiseta y velocidad del equipo; el tiempo real se deriva de la velocidad histórica, no de la estimación directa.
Historias de usuario: formato «Como quiero para »; criterios de aceptación verificables; INVEST (independiente, negociable, valiosa, estimable, pequeña, testeable).
Gestión de riesgos: identificar, analizar (probabilidad × impacto), planificar respuesta (evitar, mitigar, transferir, aceptar) y monitorear durante todo el proyecto.
Control de versiones y CI/CD: ramas cortas, integración frecuente, build automatizado con pruebas y despliegue reproducible; el diseño evoluciona con el código versionado.
Documentación de diseño: diagramas, ADRs, especificaciones de interfaz y criterios de aceptación; debe ser suficiente y actualizable, no exhaustiva.
Métricas de proceso: velocidad, lead time, cycle time, WIP (trabajo en curso) y tasa de defectos; Kanban limita el WIP para reducir el tiempo de ciclo.
Seguridad y Persistencia en el Diseño
Principios de seguridad en diseño: mínimo privilegio, defensa en profundidad, separación de deberes, fallo seguro (deny by default) y no confiar en la entrada del usuario.
OWASP Top 10 relevante al diseño: inyección SQL, control de acceso quebrado, autenticación débil, exposición de datos sensibles, configuración incorrecta y componentes vulnerables.
Prevención de inyección: consultas parametrizadas o prepared statements, validación de entrada en servidor y escape de salida según el contexto (HTML, SQL, URL).
Contraseñas: almacenar con hash lento y sal (bcrypt, scrypt, Argon2), nunca en texto plano ni con MD5/SHA-1; comparación en tiempo constante.
Persistencia: normalización hasta 3FN (elimina dependencias parciales y transitivas), desnormalización deliberada por desempeño, transacciones ACID (atomicidad, consistencia, aislamiento, durabilidad).
ORM: mapea objetos a tablas relacionales; riesgos: problema N+1, consultas generadas ineficientes y acoplamiento al esquema; usar carga perezosa o anticipada según el caso.
Diseño de API segura: autenticación con OAuth 2.0/OIDC, tokens de corta vida, HTTPS obligatorio, rate limiting, validación de esquema y versionado de endpoints.
Patrones de persistencia: Repository (abstrae el acceso a datos), Unit of Work (agrupa cambios transaccionales), Data Mapper y Active Record; Repository facilita pruebas con dobles.
Diseño de Interfaces y Experiencia de Usuario
Heurísticas de Nielsen: visibilidad del estado, coincidencia con el mundo real, control y libertad, consistencia, prevención de errores, reconocimiento sobre recuerdo, flexibilidad, diseño minimalista, recuperación de errores y ayuda.
Accesibilidad WCAG 2.x: cuatro principios POUR (perceptible, operable, comprensible, robusto); niveles A, AA y AAA; contraste mínimo 4.5:1 para texto normal y 3:1 para texto grande en AA.
Diseño de formularios: etiquetas visibles asociadas al campo, validación en línea con mensajes específicos, evitar placeholders como única etiqueta y agrupar campos relacionados.
Diseño responsivo: grids fluidos, imágenes flexibles, media queries y enfoque mobile-first; breakpoints definidos por contenido, no por dispositivos concretos.
Principios de usabilidad: affordance, feedback inmediato, prevención de errores, consistencia y reducción de carga cognitiva; el usuario no debe memorizar rutas.
Prototipado: wireframe (estructura), mockup (visual) y prototipo interactivo (comportamiento); pruebas de usabilidad con 5 usuarios revelan la mayoría de problemas graves.
Diseño de API como interfaz: nombres de recursos en plural, verbos HTTP semánticos (GET, POST, PUT, PATCH, DELETE), códigos de estado correctos y paginación explícita.
Separación de intereses en UI: modelo-vista-controlador (MVC), MVP y MVVM; la lógica de presentación no debe contener reglas de negocio.
Patrones de Diseño Avanzados y Antipatrones
Antipatrones de código: God Object, Spaghetti Code, Lava Flow, Golden Hammer, Copy-Paste Programming, Magic Numbers y Boat Anchor; se detectan con revisión de código y análisis estático.
Antipatrones de arquitectura: Big Ball of Mud, Stovepipe (sistemas aislados), Vendor Lock-in, Reinvent the Wheel y Architecture by Implication; suelen surgir de decisiones no documentadas.
Inyección de dependencias: el contenedor provee las dependencias en lugar de que la clase las instancie; variantes constructor, setter e interfaz; facilita pruebas con mocks.
Patrones de concurrencia: Active Object, Monitor Object, Half-Sync/Half-Async, Thread Pool y Reactor; el diseño debe definir quién posee cada recurso mutable.
Patrones de dominio: Entity, Value Object, Aggregate, Repository, Domain Service y Domain Event (DDD); el Aggregate define el límite de consistencia transaccional.
Patrón MVC vs. MVVM: MVC separa modelo, vista y controlador; MVVM agrega un ViewModel con data binding, común en interfaces declarativas.
Patrón Circuit Breaker: corta llamadas a un servicio fallido tras un umbral, con estados cerrado, abierto y semiabierto; evita fallos en cascada.
Diseño para pruebas: depender de interfaces, inyectar dependencias, evitar estado global y separar la lógica de efectos secundarios (I/O) del cálculo puro.
Métricas, Documentación y Comunicación del Diseño
Métricas de acoplamiento: fan-in (cuántos dependen de un módulo) y fan-out (de cuántos depende); alto fan-out indica fragilidad ante cambios.
Métricas de cohesión: LCOM (Lack of Cohesion of Methods) mide métodos que no comparten atributos; valores altos sugieren dividir la clase.
Métricas de tamaño y complejidad: líneas de código, número de métodos por clase, profundidad de herencia (DIT) y número de hijos (NOC); se interpretan en contexto, no aisladas.
Documentación de arquitectura: vistas de Kruchten, C4, diagramas de despliegue y ADRs; cada artefacto debe indicar su propósito y audiencia.
Comunicación con stakeholders: el diseño se explica con escenarios y diagramas de alto nivel para negocio; el detalle técnico se reserva para el equipo de desarrollo.
Revisión de diseño: walkthrough (informal), inspección formal con roles y checklist, y revisión por pares; la inspección formal detecta más defectos que las pruebas.
Trazabilidad: relacionar requisitos, diseño, código y pruebas; una matriz de trazabilidad revela requisitos sin diseño o sin prueba asociada.
Definición de terminado (DoD): criterios acordados como pruebas pasando, revisión de código, documentación actualizada y despliegue en entorno de pruebas.
Diseño de Software Basado en Componentes y Reutilización
Componente: unidad desplegable e independiente con interfaz provista y requerida; el diseño por componentes favorece el reemplazo sin recompilar el resto del sistema.
Interfaces provistas vs. requeridas: la primera expone lo que el componente ofrece; la segunda declara lo que necesita de otros; ambas definen el contrato de ensamblaje.
Contratos de interfaz: precondiciones, postcondiciones e invariantes; documentar el contrato permite sustituir implementaciones sin romper a los clientes.
Reutilización: caja blanca (herencia, requiere conocer el interior), caja negra (composición sobre interfaces) y frameworks (inversión de control: el framework llama al código).
Inversión de control y Hollywood Principle: «no nos llames, nosotros te llamamos»; el flujo lo controla el framework o contenedor, no la aplicación.
Diseño guiado por el dominio (DDD): lenguaje ubicuo, contextos delimitados, mapa de contextos y capas de aplicación, dominio e infraestructura; los límites del contexto definen los servicios.
Acoplamiento entre componentes: por interfaz (deseable), por datos (aceptable), por control (frágil) y por contenido (evitar); el diseño busca los dos primeros.
Versionado semántico de componentes: MAJOR para cambios incompatibles, MINOR para funcionalidad compatible y PATCH para correcciones compatibles.