1. Patrones de Diseño II
“Si la depuración es el proceso de buscar y eliminar errores, entonces la programación
debe ser el proceso de introducirlos.”
Esdger Dijkstra.
“Con el software el software en producción, la corrección de errores es como reparar un
auto mientras está siendo conducido por la carretera.”
Imagemaker IT
Agosto, 2011
4. Refactorización
• Es el cambio en un sistema software de tal forma
que no se altere su comportamiento externo (no se añade
funcionalidad) si no que mejora su estructura interna.
• Es una manera disciplinada de “limpiar” el código que
minimiza el riesgo de introducir bugs.
• Cuando se refactoriza, se mejora el diseño que se ha escrito
permitiendo que sea más fácil de comprender y cambiar.
• Esta se realiza a menudo como parte del proceso de
desarrollo de SW.
• Se debe alternar el desarrollo de nuevas funcionalidades y
casos de uso (tests) para garantizar que las mejoras no han
alterado el comportamiento del sistema.
5. Cuando aplicarla – Bad Smells
• Muchas líneas de código en las clases.
• Código duplicado (hijos del copy/paste).
• Largas listas de parámetros.
• Mal uso de colecciones y estructuras de datos
complejas
• Abuso de la configuración del software.
• Múltiples objetos con funcionalidades similares.
• Exposición de implementaciones.
• Código poco legible y/o poco mantenible.
• Shotgun Surgery
6. Over-Engineering
• En estricto chileno… abusaste de tu creatividad.
• Uso excesivo de patrones cuando no es necesario.
• Aplicación a la fuerza de tecnologías.
• Nos olvidamos de mantener las cosas simples.
• Provoca lo mismo que un mal desarrollo, es decir, código
difícil de entender y mantener.
• Extensas e inútiles jerarquías.
• No caer en “paranoia”.
8. Facade
• Tipo: Estructural
• Nivel: Componente
• Propósito: proporcionar una interface simplificada para un grupo de
subsistemas ó un sistema más complejo.
• Aplicabilidad: cuando se desee reducir el acoplamiento entre los clientes y
los subsistemas. Otro uso es cuando se de desea introducir capas entre
los subsistemas proporcionando fachadas para acceder a estos
subsistemas.
• Descripción: la intención principal del patrón no es esconder los
subsistemas, si no proporcionar más simple para un conjunto de
subsistemas, permitiendo que los clientes más avanzados puedan utilizar
las opciones más elaboradas y trabajen directamente con dichos
subsistemas.
9. Implementación
Facade: la clase que utilizan los clientes. Conoce los subsistemas utilizados y sus respectivas
Responsabilidades. Normalmente, todas las peticiones de clientes serán delegadas en los
Subsistemas apropiados.
Módulo X: Conjuntos de clases que pueden ser utilizadas directamente por los clientes
ó hacer el trabajo asignado por el objeto Facade.
10. Ventajas e Inconvenientes
• Traduce las peticiones del cliente a los subsistemas
que pueden cumplir esos llamados. La mayor parte de las
veces, una petición será delegada en más de un sistema. Como el
cliente sólo interactúa con el Facade, el funcionamiento interno
puede ser modificado, mientras que el cliente del Facade puede
permanecer igual.
11. Prototype
• Tipo: creación
• Nivel: clase única
• Propósito: Facilita la creación dinámica al definir clases cuyos objetos
pueden crear copias de si mismos.
• Descripción: Simplemente proporciona un mecanismo para que haya un
objeto utilizado como base para crear una instancia con los mismos
valores. Como proporciona un comportamiento de “creación basada en un
estado existente”, es posible que los programas lleven a cabo operaciones
como la copia dirigida por el usuario, al tiempo que permite inicializar los
objetos a un estado que ha sido establecido durante el uso del sistema.
• Aplicabilidad: Utilice el patrón cuando desee crear un objeto que sea una
copia de un objeto existente.
12. Implementación
Prototype: declara la interface para realizar la clonación.
ConcretePrototype: Clase que implementa la clonación.
Client: Realiza la petición de copia del objeto.
Patrones Relacionados
• Abstract Factory: puede utilizar prototype para crear nuevos objetos
basandose en el uso actual de la fábrica.
•Factory Method: los métodos de fabricación pueden utilizar un Prototype
para actuar como plantilla para los nuevos objetos.
13. Memento
• Tipo: de comportamiento.
• Nivel: objeto
• Propósito: Guardar una “instancia” del estado de un objeto, de forma que
pueda ser devuelto a su estado original sin revelar su contenido al resto
del mundo.
• Descripción: Los objetos mantienen un estado internamente, el cual es
accesado a través de métodos. Pero sería necesario pasar el estado actual
a otro objeto, para que sea posible restaurar el estado del objeto en un
momento posterior (deshacer). Para ello, se encapsula el estado que se
quiere conservar, utilizando memento. Un memento es un objeto que
contiene el estado interno actual del objeto Originirator. Solo el Originator
puede almacenar y recuperar información de Memento.
14. Aplicabilidad
Usar el patrón cuando se den estas condiciones:
• Debe tomarse una instantánea del estado de un objeto.
• Dicha instantánea debe ser usada para restaurar el estado original.
15. • Implementación
• Originator: crea el memento y lo utiliza para recuperar su estado.
• Memento: clase estática de Originator que contiene su estado. El originator
determina qué datos almacenar en el Memento y solo el Originator debe ser capaz
de leer el memento.
• StateHolder: el objeto que desea preservar su estado. Nunca necesita saber qué
hay en el memento; sólo necesita saber que el objeto que recibe permite restaurar
el estado del originator.
16. Ventajas e Inconvenientes
• Deja alguna información en un objeto para que sea
accesible por otro objeto utilizando control de acceso por defecto.
• Es conveniente de usar en transacciones a Bases de Datos
• Se recomienda su uso cuando se deban considerar operaciones undo/redo
• El Originator es más simple, en este patrón se da la responsabilidad de
almacenar los distintos estados a la parte solicitante (el cliente).
Patrones Relacionados
• Command: utiliza mementos para registrar el estado de acciones que no
se pueden deshacer.
• State: la mayoría de los estados utilizan el patrón memento.
17. Proxy
• Tipo: Estructural
• Nivel: componente
• Propósito: Proporcionar un representante de otro objeto, por
distintas razones, como pueden ser el acceso, la velocidad,
o la seguridad, entre otras.
• Descripción: Obliga a que las llamadas a un objeto ocurran
indirectamente a través de un objeto proxy, que actúa como
sustituto del original, delegando las llamadas a los métodos de los
objetos respectivos.
18. Implementación
Subject: Define la interface común para el RealSubject y el proxy, de modo que pueda usarse
un proxy en cualquier sitio en el que se espere un RealSubject.
RealSubject: Define el objeto real representado.
Proxy: Mantiene una referencia que permite al proxy acceder al objeto real. Proporciona una
Interface idéntica a la del subject, de manera que pueda ser sustituido. Controla el acceso al
objeto real y puede ser responsable de su creación y borrado.
19. Patrones Relacionados
• HOOP (Half Object Plus Protocol): este patrón
puede utilizar el proxy para establecer la comunicación
entre las 2 partes distribuidas del HOPP.
• Business Delegate: este patrón puede ser utilizado como un
proxy. El delegado de negocios puede ser un representante
local de un nivel de negocios.
20. Model – View – Controller
• Tipo: comportamiento
• Nivel: componente – arquitectura
• Propósito: Divide un componente ó un subsistema en tres lógicas –
modelo, vista y controlador – facilitando la modificación o personalización
de cada parte.
• El modelo: es un conjunto de clases que representan la información del
mundo real que el sistema debe procesar, desconoce la existencia de las
vistas y del controlador. Ese enfoque suena interesante, pero en la práctica
no es aplicable pues deben existir interfaces que permitan a los módulos
comunicarse entre sí.
• Modelo del dominio: Se podría decir que el modelo del dominio (o el
modelo propiamente dicho) es el conjunto de clases que un ingeniero de
software modela al analizar el problema que desea resolver.
21. Model – View - Controller
• El modelo de la aplicación: es un conjunto de clases
que se relacionan con el modelo del dominio,
que tienen conocimiento de las vistas y que implementan los mecanismos
necesarios para notificar a éstas últimas sobre los cambios que se pudieren
dar en el modelo del dominio.
• Vistas: son el conjunto de componentes que se encargan de mostrar al usuario
la información contenida en el modelo. Una vista está asociada a un modelo,
pudiendo existir varias vistas asociadas al mismo modelo; así por ejemplo, se
puede tener una vista mostrando la hora del sistema como un reloj analógico y
otra vista mostrando la misma información como un reloj digital.
• El controlador : es un objeto que se encarga de dirigir el flujo del control de la
aplicación debido a mensajes externos, como datos introducidos por el
usuario u opciones del menú seleccionadas por él. A partir de estos mensajes,
el controlador se encarga de modificar el modelo o de abrir y cerrar vistas. El
controlador tiene acceso al modelo y a las vistas, pero las vistas y el modelo no
conocen de la existencia del controlador
23. Variaciones del patrón
• Modelo push frente al modelo pull: en MVC se puede implementar una ó
más formas que el modelo envíe las actualizaciones a su vista (ó vistas) ó
que una de ellas pueda recuperar información del modelo conforme la
necesita. La elección afecta a cómo se implementan las relaciones del
sistema.
• Múltiples objetivos vista: un modelo puede proporcionar información a
más de una vista. Esto resulta particularmente útil en algunas
implementaciones de interfaces gráficas, porque los mismos datos deben
llevar algunas veces a distintas representaciones.
• Vistas “ver pero no tocar”: no todas las vistas necesitan un controlador.
Algunas proporcionarán solo una representación visual de los datos del
modelo, pero no soportan ningún cambio en el modelo de la vista.
24. Ventajas
• La aplicación se desarrolla en forma modular
• Las modificaciones en las vistas no afectan a los otros módulos.
• MVC es bastante utilizado en la actualidad en marcos de aplicación
orientados a objeto desarrollados para construir aplicaciones de
gran tamaño; Java Swing, Apache Struts, Microsoft ASP.NET, las
transformaciones XSL o incluso los documentos LATEX siguen este
patrón de diseño.
25. Anti patrones de Diseño
• Son “soluciones” negativas que presentan más
problemas que los que solucionan.
• Son una extensión natural de los patrones de diseño.
• La idea es comprender los antipatrones para intentar evitarlos
y/o recuperarse de ellos.
• Se documentan generalmente con cierto cinismo para
hacerlos fáciles de recordar.
• Según James Coplien, un antipatrón es algo que se ve como
una buena idea, pero que falla de pésima forma cuando se le
implementa.
26. Ejemplos de Anti Patrones
• Nombre antipatrón: The Blob (La mancha)
• Nombre alternativo: Winnebago and the God class.
• Afecta a: la aplicación completa.
• Solución: Refactorización de responsabilidades.
• Se produce por: flojera, estar contra el tiempo.
• Problema que provoca: manejo de funcionalidades, rendimiento, complejidad.
• Evidencia anecdótica: “Esta clase es realmente el corazón de la arquitectura”.
27. Consecuencias y síntomas
• Una sola clase con un gran número de atributos y operaciones.
• Una clase con 60 ó más atributos y operaciones claramente
indica la presencia de un blob.
• Ausencia de orientación a objetos, se programa en forma estructurada
como si tuviésemos un main.
• La clase Blob es usualmente complicada de reusar, mantener, testear, etc.
• Dicha clase es muy costosa de mantener en memoria, lo que repercute
directamente en el rendimiento de la aplicación.
• Excepción: Es aceptable cuando hacemos un wrapper de un sistema
legacy.
• Solución: Refactorizar y recomponer atributos y operaciones definiendo
de mejor forma las resposabilidades de cada funcionalidad.
28. • Nombre antipatrón: Lava Flow (Flujo de Lava).
• Nombre alternativo: Dead Code.
• Afecta a: La aplicación completa.
• Solución: mecanismo de configuración de la arquitectura.
• Se produce por: flojera.
• Problema que provoca: escasa mantenibilidad del código, problemas de
performance.
• Evidencia anecdótica: “ahh eso, ese es un código que escribió Juan y la
verdad no se si se usa todavía pero por si acaso… mejor dejémoslo. No está
documentada esa funcionalidad, dejémosla por ahora… en último de los
casos la podríamos comentar”.
29. Consecuencias y síntomas
• Clases, atributos u operaciones absolutamente injustificables
en el código.
• Código que, a pesar de no saber quién lo usa ni que función cumple, no
podemos eliminarlo.
• Si el flujo de lava no es eliminado, con el tiempo sigue causando
problemas al momento de la mantención, y nos llenamos de clases y
código ínútil.
• Excepción: Es aceptable cuando estamos trabajando en función de un
ambiente solo para generar prototipos y no requerirá mayor mantención
en el tiempo.
• Solución: la arquitectura y el diseño de clases debe estar claramente
definido, con sus funcionalidades claras, documentado, y cuando tenemos
operaciones comunes a la aplicación, esta debe ser parte de componentes
más genéricos o de arquitectura.