Diseño de Software
El módulo Diseño de Software evalúa cómo se pasa de requisitos y casos de uso a una estructura de clases, componentes y capas defendible. Las preguntas típicas muestran un fragmento de código o un diagrama descrito en texto y piden identificar el principio violado, el patrón que resuelve el problema o el efecto de una decisión sobre atributos de calidad como modificabilidad, testabilidad o acoplamiento. No basta con reconocer nombres: hay que justificar la elección y distinguir patrones parecidos.
Cohesión, acoplamiento y principios
- SRP: una clase debe tener una sola razón para cambiar (un actor), no “hacer una sola cosa” en sentido literal.
- OCP: extensible sin modificar código estable; se logra con abstracciones y polimorfismo.
- LSP: un subtipo debe poder sustituir al supertipo sin romper contratos (precondiciones no más estrictas, postcondiciones no más débiles).
- ISP: interfaces pequeñas y específicas del cliente, en lugar de una interfaz “gorda”.
- DIP: los módulos de alto nivel dependen de abstracciones, no de detalles; la inyección de dependencias es una técnica para lograrlo, no el principio.
- GRASP: Experto (asignar responsabilidad a quien tiene la información), Creador, Bajo acoplamiento, Alta cohesión, Controlador, Indirección, Variaciones protegidas.
Patrones, UML y arquitectura
GoF se agrupa en creacionales (Abstract Factory, Builder, Factory Method, Prototype, Singleton), estructurales (Adapter, Bridge, Composite, Decorator, Facade, Proxy) y de comportamiento (Command, Observer, State, Strategy, Template Method, Visitor). En UML, la agregación usa rombo hueco y la composición rombo relleno: en la composición el todo controla el ciclo de vida de la parte. La realización de una interfaz es línea discontinua con triángulo hueco; la generalización, línea continua con triángulo hueco.
Ejemplo trabajado
Una clase ProcesadorDePagos contiene un if/else por tipo de pago, abre la conexión a base de datos y escribe el log. Razonamiento: (1) viola SRP, porque concentra selección, persistencia y registro, que cambian por actores distintos; (2) viola OCP, porque cada nuevo método de pago obliga a modificar la clase; (3) viola DIP, porque depende de una conexión concreta. Refactor: interfaz MetodoPago con implementaciones (Strategy), una fábrica que resuelve la selección, un RepositorioPago inyectado y un logger como dependencia. Efecto: alta cohesión por clase, bajo acoplamiento hacia abstracciones y pruebas unitarias sin base de datos.
Errores que cuestan puntos
- Confundir Strategy con State: State cambia el comportamiento según el estado interno y normalmente define transiciones.
- Confundir Factory Method (una jerarquía, un producto) con Abstract Factory (familias de productos relacionados).
- Decir que Singleton mejora la testabilidad: introduce estado global y dificulta el aislamiento.
- Usar un patrón sin justificar el problema: sobreingeniería y acoplamiento innecesario.
- Presentar MVC como patrón GoF: es un patrón arquitectónico de separación de responsabilidades.
- Invertir agregación y composición, o confundir dependencia (línea discontinua con flecha abierta) con asociación.