Patrones de diseño

1,897 views
1,740 views

Published on

Un resumen de los 23 Patrones de Diseño de The Gang of Four. Espero que les sirva de mucho

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,897
On SlideShare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
69
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Patrones de diseño

  1. 1. Patrones de Diseño Abimael Desales López Para Java Developers Mexico
  2. 2. A cerca de los Patrones de Diseño Esta refcard Patrones de Diseño proporciona una rápida referencia a los 23 patrones de diseño de Gang of Four originales, como se listan en el libro Design Patterns: Elements of Reusable Object Oriented Sotware. Cada patrón incluye diagramas de clase, explicación, información de uso, y un ejemplo del mundo real. Patrones creacionales: Usados para construir objetos que pueden ser desacoplados de su sistema de implementación. Patrones estructurales: Usados para formar grandes estructuras de objetos entre muchos objetos dispares Patrones de comportamiento: Usados para manejar algoritmos, relaciones, y responsabilidades entre objetos. Scope del objeto: Trata con relaciones de objetos que pueden ser cambiadas en tiempo de ejecución. Scope de la clase: Trata con relaciones de clases que pueden ser cambiadas en tiempo de compilación,
  3. 3. Patrones y sus tipos Abstract Factory Adapter Bridge Builder Chain of Responsability Command Composite Decorator Facade Factory Method Flyweight Interpreter Iterator Mediator Memento Prototype Proxy Observer Singleton State Strategy Template Method Visitor C S B C C C C S S S S S S B B B B B B B B B B
  4. 4. Chain of Responsability Propósito • Le proporciona a más de un objeto la oportunidad de manejar una request vinculando los objetos de recepción. Usado cuando: • Múltiples objetos pueden manejar una request y la request no tiene que ser un objeto específico. • Un conjunto de objetos debe ser capaz de manejar una request con el handler determinado en tiempo de ejecución. • Una request que no está siendo manejada es una salida potencial aceptable Ejemplo: El manejo de excepciones en algunos lenguajes implementa este patrón. Cuando una excepción es lanzada en un método el runtime checa para ver si el método tiene un mecanismo para manejar la excepción o si debe ser pasado a la pila de llamadas. Cuando es pasado a la pila de llamadas, el proceso se repite hasta que el código para manejar la excepción es encontrado o hasta que no haya más objetos padre para manejar la request
  5. 5. Command Propósito • Encapsula una request permitiéndole ser tratada como un objeto. Esto permite a la request ser manejada tradicionalmente en relaciones basadas en objetos como encolamientos y callbacks. Usado cuando: • Necesitas funcionalidad de callback. • Las requests necesitan ser manejadas en tiempos variantes o en órdenes variantes. • Es necesario un historial de requests. • El invocador debe estar desacoplado del objeto que maneja la invocación. Ejemplo: Las colas de jobs son ampliamente usadas para facilitar el procesamiento asíncrono de algoritmos. Utilizando el patrón command, la funcionalidad a ser ejecutada puede ser dada a una cola de jobs para procesar sin alguna necesidad para que la queue tenga conocimiento de la implementación real que está invocando. El objeto command que está encolado implementa su algoritmo particular en los confines de la interface que la cola está esperando.
  6. 6. Interpreter Ejemplo: Aventuras basadas en texto, ampliamente populares en los 1980’s proporcionan un buen ejemplo de esto. muchos tenían comandos simples como un “step down” que permitían recorrer el juego. Estos comandos podrían ser anidados de forma que alteraran su significado. Por ejemplo, “go in” resultaría en una diferente salida que “go up”. Creando una jerarquía de comandos basada contra el comando y el calificador la aplicación podría fácilmente mapear muchas variaciones del comando a un árbol de acciones relacionado. Propósito • Define una representación de una gramática, así como un mecanismo para comprender para comprender y actuar contra la gramática. Usado cuando: • Hay una gramática a interpretar que puede ser representada como grandes árboles de sintaxis. • la gramática es simple. • No es importante la eficiencia. • Es deseado el desacoplamiento de la gramática de las expresiones fundamentales.
  7. 7. Iterator Propósito • Permite accesar a los elementos de un objeto agregado sin permitir el acceso a su representación fundamental, esto es, a su lógica interna. Usado cuando: • Se necesitan accesos a elementos sin accesar a la representación completa. • Son necesarios múltiples o concurrentes recorridos de los elementos. • Existen sutiles diferencias entre los detalles de implementación de varios iteradores. • Es necesaria una interfaz uniforme para recorrido. Ejemplo: La implementación Java del patrón iterator permite a los usuarios recorrer varios tipos de conjuntos de datos sin preocuparse por la implementación particular de la colección. Ya que los clientes simplemente interactúan con la interface iterator, las colecciones son dejadas para definir el iterator apropiado para ellas mismas. Algunos permitirán acceso completo a los conjuntos de datos particulares, mientras que otros pueden restringir ciertas funcionalidades, tales como remover elementos.
  8. 8. Mediator Propósito • Permite el débil acoplamiento encapsulando los conjuntos separados de objetos que interactúan y se comunican con los otros. Permite a las acciones de cada conjunto de objetos variar de uno a otro independientemente. Usado cuando: • La comunicación entre conjuntos de objetos está bien definida y es compleja. • Existen muchas relaciones y es necesario un punto común de control o comunicación. Ejemplo: El software de lista de correos mantiene el rastro de quien está firmado a la lista de correo y proporciona un sólo punto de acceso a través del cual cualquier persona puede comunicarse con la lista completa. Sin la implementación de un mediador una persona que espera enviar un mensaje al grupo tendría que mantener el rastreo constantemente de quien se firmaó y quien no. Al Implementar el patrón mediator el sistema es capaz de recibir mensajes desde cualquier punto, luego determina a qué bandejas enviar el mensaje, sin que el emisor del mensaje se tenga que preocupar de la lista real de receptores.
  9. 9. Memento Propósito • Permite capturar y externalizar el estado interno de un objeto de forma que pueda ser restaurado posteriormente, todo sin violar la encapsulación. Usado cuando: • El estado interno de un objeto debe se guardado y restaurado en un momento posterior. • El estado externo no puede ser expuesto por interfaces sin exponer la implementación. • Los límites de la encapsulación deben ser preservados. Ejemplo: La funcionalidad deshacer puede fácilmente ser implementada usando el patrón memento. Serializando y deserializando el estado de un objeto antes que el cambio ocurra podemos preservar una instantánea de ello que puede ser posteriormente restaurado cuando el usuario elija deshacer la operación
  10. 10. Observer Propósito • Permite a uno o más objetos ser notificado de cambios de estado en otros objetos en el sistema. Usado cuando: • Los cambios de estado en uno o más objetos deben disparar comportamiento en otros objetos. • Se requieren capacidades de difusión. • Una comprensión existe que los objetos estarán cegados a expensas de notificación. Ejemplo: Este patrón puede ser encontrado en casi todos los entornos de GUI. Cuando los botones, textos y otros campos son colocados en aplicaciones, la aplicación generalmente registra como listeners para estos controles. Cuando un usuario dispara un evento, como lo es hacer click en un botón, el control itera a través de sus observers registrados y envía una notificación a cada uno.
  11. 11. State Propósito • Ata las circunstancias de los objetos a sus comportamientos, permitiéndole al objeto comportarse en diferentes formas basado contra su estado interno. Usado cuando: • El comportamiento de un objeto debe ser influido por su estado. • Condiciones complejas atan el comportamiento del objeto a su estado . • Las transiciones entre estados necesitan ser explícitas. Ejemplo: Un objeto email puede tener varios estados, todos de los cuales cambiarán como el objeto maneje diferentes funciones. Si el estado es “no enviado” entonces la llamada a send() va a enviar el mensaje mientras que una llamada a recallMessage() ya sea que lance un error o haga nada. Sin embargo, si el estado es “enviado” entonces la llamada a send() ya sea que lance un error o haga nada mientras la llamada a recallMesage() intentará enviar una notificación a las bandejas. Para evitar sentencias condicionales en la mayoría o todos los métodos habría múltiples objetos state que manejen la implementación con respecto a su estado particular. Las llamadas en el objeto Email sería entonces delegadas abajo al objeto state apropiado para que la maneje.
  12. 12. Strategy Propósito • Define un conjunto de algoritmos encapsulados que pueden ser intercambiados para llevar a cabo un comportamiento específico. Usado cuando: • La única diferencia entre muchas clases relacionadas es su comportamiento. • Son requeridas múltiples versiones o variaciones de un algoritmo. • Algoritmos que accesen o utilicen datos que llaman código no deben ser expuestos. • El comportamiento de una clase debe ser definida en tiempo de ejecución. • Las sentencias condicionales son complejas y difíciles de mantener. Ejemplo: Cuando se importan datos en un nuevo sistema diferentes algoritmos de validación pueden ser ejecutados basados en el conjunto de datos. Por medio de la configurando del import para qué estrategias la lógica condicional para determinar qué conjunto de validación a ejecutar puede ser removido y el import pueda ser desacoplado del código de validación real. Esto nos permitirá dinámicamente llamar a una o más estrategias durante el import.
  13. 13. Template Method Propósito • Identifica el framework de un algoritmo, permitiendo implementar las clases para definir el comportamiento real. Usado cuando: • Una sola implementación abstracta de un algoritmo es necesaria. • El comportamiento común entre subclases debe ser localizado a una clase común. • Las clases padre deben ser capaces de invocar comportamiento uniformemente en sus subclases. • La mayoría o todas las subclases necesitan implementar el comportamiento. Ejemplo: Una clase padre InstantMessage, posiblemente tendrá todos los métodos requeridos para manejar el envío de un mensaje. Sin embargo, la serialización real de los datos a enviar puede variar dependiendo de la implementación. Un mensaje de video y un mensaje de texto plano requerirán diferentes algoritmos con fin de serializar los datos correctamente. Las subclases de InstantMessage pueden proporcionar su propia implementación del método de serialización, permitiéndole a la clase padre trabajar con ellas sin comprender los detalles de su implementación.
  14. 14. Visitor Propósito • Permite a una o más operaciones ser aplicadas a un conjunto de objetos en tiempo de ejecución, desacoplando las operaciones de la estructura del objeto. Usado cuando: • La estructura del objeto debe tener muchas operaciones no relacionadas ejecutadas contra ella. • La estructura del objeto no puede cambiar pero las operaciones ejecutadas en él pueden. • Las operaciones deben ser ejecutadas en las clases concretas de la estructura de un objeto. • Exponer el estado interno u operaciones de la estructura del objeto es inaceptable. • Las operaciones deben ser capaces de operar en múltiples estructuras de objetos que implementan los mismos conjuntos de interfaces. Ejemplo: Calcular impuestos en diferentes regiones sobre conjuntos de facturas requeriría muchas variaciones diferentes de lógica de cálculo. Implementando un visitor permite a la lógica estar desacoplada de los elementos de línea y factura. Esto permite a la jerarquía de elementos ser visitadas por el código de cálculo que puede entonces aplicar a las tarifas adecuadas para la región. Cambiar regiones es tan simple como sustituir un visitor diferente.
  15. 15. Adapter Propósito • Permite que clases con interfaces diferentes trabajen juntas creando un objeto común por el cual puedan comunicarse e interactuar. Usado cuando: • Una clase a ser usada no reúne los requerimientos de interface. • Condiciones complejas atan el comportamiento del objeto a su estado. • Las transiciones entre estados necesitan ser explícitas. Ejemplo: Una aplicación de facturación necesita interactuar con una aplicación de RH con el fin de intercambiar datos de empleados, sin embargo cada una tiene su propia interface e implementación para el objeto Empleado. Además, el SSN está almacenado en formatos diferentes por cada sistema. Creando un adapter podemos crear una interface común entre las dos aplicaciones que les permite comunicarse usando sus objetos nativos y es capaz de transformar el formato SSN en el proceso.
  16. 16. Bridge Propósito • Define una estructura de objeto abstracta independientemente de la estructura del objeto de implementación con el fin de limitar el acoplamiento. Usado cuando: • Las abstracciones e implementaciones no deben estar vinculadas en tiempo de compilación. • Las abstracciones e implementaciones deben ser independientemente extensibles. • Cambios en la implementación de una abstracción no deben impactar en los clientes. • Los detalles de implementación deben estar escondidos del cliente Ejemplo: La JVM tiene su propio conjunto nativo de funciones que abstraen el uso de windowing, logging del sistema, y ejecución de byte code, pero la implementación real de estas funciones es delegada al sistema operativo en el que la JVM está corriendo. Cuando una aplicación instruye a la JVM de presentar una ventana delega la llamada a presentación a la implementación concreta de la JVM que sabe cómo comunicarse con el sistema operativo con el fin de presentar la ventana.
  17. 17. Composite Propósito • Facilita la creación de jerarquía de objetos donde cada objeto puede ser tratado de forma independiente como un conjunto de objetos anidados a través de la misma interface. Usado cuando: • Son necesarias representaciones jerárquicas de objetos. • Los objetos y composiciones de objetos deben ser tratadas uniformemente. Ejemplo: A veces la información desplegada en un carrito de compras es el producto de un sólo ítem mientras que otras veces es una agregación de múltiples elementos. Implementado ítems como compuestos podemos tratar los agregados y los ítems de la misma forma, permitiéndonos simplemente iterar sobre el árbol e invocar funcionalidad en cada ítem. Llamando al método getCost() en cualquier nodo dado obtendría el costo de ese ítem mas el costo de todos los ítems hijos, permitiéndole a los ítems ser tratados uniformemente si ellos eran ítems solos o grupos de ítems.
  18. 18. Decorator Propósito • Permite la envoltura dinámica de objetos con el fin de modificar sus responsabilidades y comportamientos existentes. Usado cuando: • Las responsabilidades y comportamientos de los objetos deben ser dinámicamente modificables. • Las implementaciones concretas deben estar desacopladas de responsabilidades y comportamientos. • Subclasificar para llevar a cabo modificaciones es impráctico o imposible. • La funcionalidad específica no debe residir alta en la jerarquía de objetos. • Una cantidad de pocos objetos rodeando a una implementación concreta es aceptable Ejemplo: Muchos conjuntos de negocios suben sus sistemas de mail para tomar ventaja de los decorators. Cuando los mensajes son enviados desde alguien en la compañía a una dirección externa el servidor de mail decora el mensaje original con información de copyright y confidencialidad. Tan pronto como el mensaje permanece interno la información no es agregada. Esta decoración le permite al mismo mensaje permanecer sin cambio hasta que una decisión de ejecución se haga para envolver el mensaje con información adicional.
  19. 19. Facade Propósito • Proporciona una sola interface a un conjunto de interfaces en un sistema. Usado cuando: • Una sola interface es necesaria para proporcionar acceso a un sistema complejo. • Hay muchas dependencias entre implementaciones del sistema y clientes. • Los sistemas y subsistemas deben estar en capas. Ejemplo: Exponiendo un conjunto de funcionalidades a través de un web service el código cliente sólo necesita preocuparse sobre la sola interface que está siendo expuesta a ellos y no a las relaciones complejas que pueden o no existir tras la capa de web service. Una sola llamada a servicio que puede actualizar un sistema con nuevos datos realmente puede involucrar comunicación con muchas bases de datos y sistemas, sin embargo este detalle está escondido debido a la implementación del patrón facade.
  20. 20. Flyweight Propósito • Facilita la reutilización de muchos objetos de grano fino, haciendo la utilización de grandes números de objetos más eficiente. Usado cuando: • Muchos objetos son usados y el costo de almacenamiento es alto. • La mayoría de cada uno de los estados del objeto pueden ser hechos extrínsecos. • Algunos objetos compartidos pueden remplazar a muchos no compartidos. • La identidad de cada objeto no importa Ejemplo: Los sistemas que permiten que los usuarios definan sus propios flujos de aplicaciones frecuentemente tienen una necesidad de mantener el rastreo de grandes números de campos, páginas, y otros elementos que son casi idénticos unos con otros. Haciendo estos elementos en flyweights todas las instancias de cada objeto pueden compartir el estado intrínseco mientras mantienen separado el estado extrínseco. El estado intrínseco almacenaría las propiedades compartidas, tales como la forma en que un textbox se ve, cuantos datos puede contener, y qué eventos expone. El estado extrínseco almacenaría las propiedades no compartidas, tales como las pertenencias del elemento, cómo reaccionar ante el click de un usuario, y cómo manejar eventos.
  21. 21. Proxy Propósito • Permite para el control de acceso a nivel de objeto actuar como un pase a través de una entidad o un marcador de posición de objeto. Usado cuando: • El objeto que está siendo representado es externo al sistema. • Los objetos necesitan ser creados bajo demanda. • Se requiere control de acceso para el objeto original. • Se requiere funcionalidad agregada cuando un objeto es accesado Ejemplo: Aplicaciones de libro mayor frecuentemente proporcionan una forma de reconciliar sus declaraciones bancarias con sus datos de libro mayor bajo demanda, automatizando muchos de los procesos. La operación real de comunicarse con una tercera parte es una operación relativamente cara que debe limitarse. Mediante el uso de un proxy para representar el objeto comunicaciones podemos limitar el número de veces o los intervalos en que la comunicación es invocada. Además, podemos envolver la instanciación compleja del objeto comunicación dentro de la clase proxy, desacoplando el código de invocación de los detalles de implementación.
  22. 22. Abstract factory Propósito • Provee una interface que delega las llamadas a creación a una o más clases concretas con el fin de liberar objetos específicos. Usado cuando: • La creación de objetos debe ser independiente del sistema que los está utilizando. • Los sistemas deben ser capaces de usar múltiples familias de objetos. • Las familias de objetos deben ser usadas juntas. • Las librerías deben ser publicadas sin exponer los detalles de implementación. • Las clases concretas deben estar desacopladas de los clientes. Ejemplo: Los editores de email permitirán editar en múltiples formatos incluyendo texto plano, texto rico, y HTML. Dependiendo del formato que esté siendo usado, necesitan crearse diferentes objetos. Si el mensaje es texto plano entonces podría ser un objeto body que representara sólo texto plano y un objeto attachment simplemente encriptaría el attachment en base 64. Si el mensaje es HTML entonces el objeto body representaría HTML codificado y el objeto attachment permitiría la representación inline y un attachment estándar. Utilizando un abstract factory para la creación podemos asegurar que el conjunto de objetos apropiados serán creados basados contra el estilo de email que está siendo enviado.
  23. 23. Builder Propósito • Permite la creación dinámica de objetos basados contra algoritmos intercambiables fácilmente. Usado cuando: • Los algoritmos de creación de objetos deben estar desacoplados del sistema. • Se requieren múltiples representaciones de algoritmos de creación. • La adición de funcionalidad de nueva creación sin cambiar el código core es necesaria. • Se requiere control en tiempo de ejecución sobre el proceso de creación. Ejemplo: Una aplicación de transferencia de archivos posiblemente podría usar diferentes protocolos para enviar archivos y el objeto de transferencia real que será creado será directamente dependiente del protocolo elegido. Usando un builder podemos determinar el builder correcto a usar para instanciar el objeto correcto. Si la elección es FTP entonces builder FTP sería usado cuando se crea el objeto.
  24. 24. Factory Method Propósito • Expone un método para crear objetos, permitiéndole a las subclases controlar el proceso de creación real. Usado cuando: • Una clase no sabrá qué clases le requerirán crear. • Las subclases pueden especificar qué objetos deben ser creados. • Las clases padre desean diferir la creación a sus subclases. Ejemplo: Muchas aplicaciones tienen algunas estructuras de usuarios y grupos para seguridad. Cuando la aplicación necesita crear un usuario, generalmente delegará la creación del usuario a múltiples implementaciones del usuario. El objeto usuario padre manejará la mayoría de las operaciones para cada usuario pero las subclases definirán el método factory que maneja la distinción en la creación de cada tipo de usuario. Un sistema puede tener los objetos AdminUser y StandardUser cada uno de los cuales extiende del objeto User. El objeto AdminUser puede ejecutar algunas tareas extra para asegurar el acceso mientras que el objeto StandardUser puede hacer lo mismo para limitar el acceso.
  25. 25. Prototype Propósito • Crear objetos basados contra una plantilla de objetos existentes a través de la clonación. Usado cuando: • La composición, creación y representación de objetos debe estar desacoplado de un sistema. • Las clases a crear son especificadas en tiempo de ejecución. • Existe un número limitado de combinaciones de estado en un objeto. • Se requiere que los objetos o estructuras de objetos sean idénticas o semejantes a otros objetos existentes o estructuras de objetos. • La creación inicial de cada objeto es una operación costosa. Ejemplo: Los dispositivos de procesamiento de tarifas requieren la búsqueda de muchos valores de configuración diferentes, haciendo la inicialización del dispositivo un proceso relativamente costoso. Cuando múltiples instancias del dispositivo son necesarias, dígase para importar datos en forma multi hilo, el costo de inicializar muchos dispositivos es alto. Utilizando el patrón prototype podemos asegurar que solamente una copia del dispositivo tiene que ser inicializada entonces simplemente clonar el dispositivo para crear un duplicado del objeto ya inicializado. El beneficio agregado de esto es que los clones pueden ser racionalizados para que solamente incluyan los datos relevantes para su situación.
  26. 26. Singleton Propósito • Asegura que sólo una instancia de la clase es permitida en un sistema. Usado cuando: • Se requiere exactamente una instancia de una clase . • Es necesario el acceso controlado a un sólo objeto. Ejemplo: La mayoría de los lenguajes proporcionan algún ordenamiento de objetos del sistema o entorno que permite al lenguaje interactuar con el sistema operativo nativo. Ya que la aplicación está físicamente corriendo en sólo un sistema operativo sólo hay una necesidad cada vez para una sola instancia de este objeto del sistema. El patrón singleton sería implementado por el runtime del lenguaje para asegurar que sólo una copia del objeto del sistema es creado y asegura que sólo a los procesos apropiados se les permite accesarlos.
  27. 27. GRACIAS No olvides visitar nuestra página en Facebook y regalarnos un Like. www.facebook.com/JavaDevelopersMexico ¡Descarga y Comparte!

×