Tema 13: Diseño Basado en Patrones
Título de la Clase: Ingeniería del Software - Diseño Basado en Patrones Resumen Ejecutivo: Esta sesión introduce el concepto de patrones como soluciones probadas a problemas recurrentes en el diseño de software, destacando su papel fundamental en la reutilización. Se exploran las diferencias entre bibliotecas, frameworks y patrones, profundizando en casos prácticos como Delegate, Inyección de Dependencias y Singleton. El objetivo es entender que el diseño no es solo creatividad, sino el uso inteligente de estructuras estandarizadas para garantizar la calidad y eficiencia del sistema.
Conceptos Clave
-
Reutilización de Software: Capacidad de usar elementos ya desarrollados (código, diseño o arquitectura) en nuevos contextos para ahorrar tiempo y evitar errores.
-
Patrón: Una solución predefinida y documentada para un problema de diseño común dentro de un contexto específico.
-
Inversión de Control (IoC): Principio donde el flujo de ejecución es gestionado por un componente externo (como un framework) en lugar de la aplicación principal.
-
Acoplamiento: El grado de dependencia entre diferentes componentes de software; el uso de patrones busca reducirlo (Bajo acoplamiento).
Desarrollo del Temario
1. Reutilización: El Diferencial de la Ingeniería del Software
A diferencia de otras ingenierías (como la civil o de caminos), la ingeniería de software permite "duplicar" y "transportar" componentes de forma inmediata. El profesor enfatiza que no solo reutilizamos código, sino también conocimiento y estructuras de control.
Se identifican cuatro niveles de reutilización (representados visualmente en las diapositivas con zonas sombreadas):
-
Biblioteca (Library): Reutilización funcional. El programador implementa el control y llama a funciones de la biblioteca (ej.
printfen C). -
Framework: Reutilización de la estructura de comportamiento. El framework tiene el control y llama a tu código (ej. eventos en Android como
onCreate). -
Patrón de Diseño: Reutilización de conceptos y estructuras de resolución de problemas a menor escala.
-
Arquitectura Software: Reutilización de sistemas completos y sus subsistemas (ej. MVC).
Cita del Profesor: "Un ingeniero de caminos no puede reutilizar un túnel. Puede reutilizar el conocimiento... nosotros sí podemos pillar un trozo de túnel, copiarlo e instalarlo en otro sitio de manera inmediata. Eso nos hace una disciplina diferente".
2. Anatomía y Clasificación de un Patrón
Un patrón no es solo código; es una "receta" formalizada que debe incluir:
-
Nombre, Contexto y Problema: ¿Qué situación queremos resolver?.
-
Solución y Fuerzas: Atributos de adaptación del patrón.
-
Consecuencias: Ventajas y, frecuentemente, un aumento en la complejidad del diseño a cambio de mayor generalidad.
Jerarquía de Patrones:
-
Patrones Arquitectónicos: Estructura fundamental del sistema (Ej: MVC, MVVM, Capas).
-
Patrones de Diseño: Resolución de problemas específicos dentro de un contexto (Ej: Observer, Delegate).
-
Idiomas: Patrones de bajo nivel específicos de un lenguaje de programación concreto.
3. El Patrón Delegate (Delegación)
Es la base de la inversión de control. En este patrón, un objeto ofrece un servicio pero no lo implementa directamente; en su lugar, delega la ejecución en un objeto especialista.
Ejemplo Práctico (El Contratista): Imagina una reforma en casa. Tú hablas con el Contratista (Clase C). Él te dice que sabe "pintar" y "arreglar tuberías". Sin embargo, él no hace el trabajo; cuando le pides pintar, llama a un Pintor (Clase A), y cuando pides fontanería, llama a un Fontanero (Clase B). Tú, como cliente, solo interactúas con el contratista.
¡OJO AL DATO!: La ventaja principal es que permite modificar el comportamiento en tiempo de ejecución simplemente cambiando el objeto delegado.
4. Inyección de Dependencias (DI)
Evoluciona a partir del Delegate y la Inversión de Control. Permite que las responsabilidades de un objeto no estén ligadas estáticamente.
-
Sin DI: El objeto debe saber cómo crear a sus especialistas internamente (acoplamiento fuerte).
-
Con DI: Un agente externo "inyecta" el especialista que el objeto debe usar a través de un setter o constructor.
Caso del Robot:
Un Robot tiene un CuerpoRobot. Si le inyectamos un CuerpoPajaro, el método robot.volar() funcionará. Si le inyectamos un CuerpoCocodrilo, el mismo método robot.volar() dirá "No sé volar". El cliente siempre llama al mismo método, pero el comportamiento cambia según la dependencia inyectada.
5. El Patrón Singleton
Garantiza que una clase tenga una única instancia en todo el sistema y proporciona un punto de acceso global a ella.
Implementación Técnica:
-
Atributo estático privado de la propia clase (
instance). -
Constructor privado (nadie más puede hacer
new). -
Método estático público (ej.
getInstance()) que crea la instancia si es nula o devuelve la ya existente .
¡OJO AL DATO!: Es extremadamente útil para gestionar recursos compartidos como conexiones a bases de datos.
Anécdota de Examen (Caso Real Mega): El profesor relata cómo un error de tipo NullPointerException que ocurría aleatoriamente en la app de Android de Mega se solucionó aplicando un Singleton para el
DatabaseHandler. Esto evitó la creación masiva de conexiones que colapsaban la memoria en dispositivos antiguos.
Preguntas de Autoevaluación
-
¿Cuál es la diferencia fundamental entre una biblioteca y un framework respecto al control de la ejecución?
-
¿Por qué se dice que un patrón suele aumentar la complejidad del diseño pero mejora la reutilización?
-
Explique cómo el patrón Delegate facilita la inversión de control.
-
¿Qué tres elementos técnicos son imprescindibles para implementar un patrón Singleton en Java?
-
En el ejemplo del robot, ¿qué beneficio aporta la Inyección de Dependencias si decidimos añadir un nuevo tipo de cuerpo (ej. un Pez)?