patrones de diseño ii
TRANSCRIPT
Patrones de Diseño II
Imagemaker ITAgosto, 2011
“Si la depuración es el proceso de buscar y eliminar errores, entonces la programacióndebe 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.”
Temario
• Reutilización• Refactorización• Cuando aplicarla – Bad Smells• Over-Engineering• Facade• Prototype• Memento• Proxy• Model – View – Controller• Antipatrones• Ejemplos
ReutilizaciónHistóricamente se ha buscado la reutilización en el desarrollo de software
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.
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
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”.
Gráficamente Over-engineering
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.
Implementación
Facade: la clase que utilizan los clientes. Conoce los subsistemas utilizados y sus respectivasResponsabilidades. Normalmente, todas las peticiones de clientes serán delegadas en losSubsistemas apropiados.
Módulo X: Conjuntos de clases que pueden ser utilizadas directamente por los clientesó hacer el trabajo asignado por el objeto Facade.
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.
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.
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.
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.
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.
• 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.
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.
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.
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 unaInterface 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.
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.
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.
• 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
Model – View - Controller
Implementación
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.
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.
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.
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”.
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.
• 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”.
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.
非常感謝您 !(Muchas gracias!)