viernes, 5 de abril de 2013

Patrones de diseño

>
Los patrones conducen a arquitecturas más pequeñas,
 más simples y más comprensibles.
G. Booch

PATRONES DE DISEÑO DE CREACIÓN

 Inicialización y configuración de objetos
  • Fábrica Abstracta  (Abstract Factory): El problema a solucionar por este patrón es el de crear diferentes familias de objetos, como por ejemplo la creación de interfaces gráficas de distintos tipos (ventana, menú, botón, etc.).
  •  Constructor (Builder): El objetivo es conseguir que la construcción de un OBJETO COMPUESTO sea independiente de su REPRESENTACIÓN, de manera que la CONSTRUCCIÓN no se vea afectada por el hecho de que cambie su forma de REPRESENTACIÓN.
  • Método de Fabricación (Factory Method): Parte del principio de que las subclases determinan la clase a implementar.
  •  Prototipado  (Prototype): Se basa en la clonación de ejemplares copiándolos de un prototipo.
  • Singleton: Restringe la instanciación de una clase o valor de un tipo a un solo objeto.

PATRONES DE DISEÑO ESTRUCTURALES

 Separan la interfaz de la implementación. Se ocupan de cómo las clases y objetos se agrupan, para formar estructuras más grandes.
  • Ejecutor Agregado (Aggregate Enforcer): En general, las clases se diseñan para llevar manejar datos y una funcionalidad. Algunos objetos pueden contener otros objetos como sus partes. Tales objetos, los cuales son la unión de otros objetos, se denominan objetos agregados.
  • Adaptador (Adapter): En general, los clientes de una clase acceden a los servicios ofrecidos
    por la clase a través de su interfaz. A veces, una clase existente puede proporcionar la funcionalidad requerida por un cliente, pero su interfaz no puede ser lo que el cliente espera. Esto podría suceder debido a diversas razones, por ejemplo, la interfaz existente puede ser demasiado detallada, o puede carecer de detalle, o la terminología utilizada por la interfaz puede ser diferente de lo que el cliente está buscando. En tales casos, la interfaz existente tiene que ser convertida en otra interfaz, lo que el cliente espera,  preservando la reutilización de la clase existente.
  • Cadena de responsabilidad (Chain Of Responsability): Cuando hay más de un objeto que puede administrar o atender una solicitud de un cliente, el patrón CoR recomienda dar a cada uno de esos objetos una oportunidad para procesar las solicitudes de manera secuencial. Aplicando el patrón CoR, cada uno de esos potenciales objetos administradores, pueden ser organizados en forma de una cadena, con cada objeto, mediante un puntero al próximo objeto de la cadena.
  • Counting Proxy: El patrón counting proxy es útil para diseñar un conjunto de operaciones tales como registro y conteo que son requeridas para ser ejecutadas antes y/o después que un objeto cliente invoca un método o un servicio de un objeto proveedor. En lugar de mantener la implementación de esas operaciones adicionales dentro del objeto proveedor de servicios, el patrón Counting Proxy sugiere encapsular la funcionalidad adicional en un objeto aparte referenciado como counting proxy. Una de las características de un objeto bien diseñado es que ofrece una funcionalidad enfocada. En otras palabras un objeto, idealmente, debería hacer cosas que no estén relacionadas. Encapsulando el registro, el conteo y otras funcionalidades similares en un objeto separado, deja al objeto proveedor de servicios con solamente las funcionalidades que ofrece du diseño. En otras palabras, le permite al objeto proveedor de servicios realizar una tarea bien definida.
  • Envoltorio (Decorator): Permite añadir dinámicamente funcionalidad a una clase existente, evitando heredar sucesivas clases para incorporar la nueva funcionalidad.
  • Fachada (Facade): Permite simplificar la interfaz para un subsistema. El patrón  fachada permite negociar con un subsistema de clases. Un subsistema es un conjunto de clases que trabajan en conjunto con el fin de proporcionar un conjunto de características relacionadas (funcionalidad).
  • Objeto en Cache (Object Cache): El concepto de mantener una copia de un objeto en la memoria, en alguna forma, con el objetivo de proveer un tiempo de respuesta más rápido a las solicitudes de los clientes, es llamado caching (esconder, depositar en memoria). Esto se hace cuando la construcción de un nuevo objeto es costoso en términos de procesamiento. El objeto en la memoria no se almacena por siempre.
  • Apoderado (Proxy): El objeto proxy interactúa con el objeto destino en nombre de un objeto de cliente y se encarga de los detalles específicos de la comunicación con el objeto de destino. De esta forma, los objetos clientes ya no necesitan negociar el acceso a los servicios del objeto destino.
  • Puente (Bridge): Desacopla una abstracción de su implementación permitiendo modificarlas independientemente.
  • Proxy Virtual: El patrón virtual proxy es una técnica de ahorro de memoria que recomienda posponer la creación del objeto en los siguientes debido a que, el crear tal objeto es costoso en términos de la utilización de la memoria o por el procesamiento involucrado. En una aplicación típica, diferentes objetos constituyen las diferentes partes de la funcionalidad. Cuando una aplicación arranca, puede ser que no necesite de todos los objetos de manera inmediata. En tales casos, el patrón virtual proxy sugiere aplazar objeto creación hasta que la aplicación lo necesite. El objeto se crea la primera vez que se le hace referencia en la aplicación,  y la misma instancia se reutiliza a partir de ese punto en adelante.

PATRONES DE DISEÑO DE COMPORTAMIENTO

 Más que describir objetos o clases, describen la comunicación entre ellos.
  • Comando (Command): En general una aplicación orientada a objetos consiste en la interacción de objetos que ofrecen una funcionalidad. En respuesta a la interacción del usuario, la aplicación ejecuta algún tipo de procesamiento. Para este propósito la aplicación utiliza servicios de diferentes objetos para los requisitos de procesamiento. En términos de implementación, la aplicación puede depender de un objeto designado que invoca los métodos de esos objetos mediante el paso de argumentos (Ver Figura 1). A este objeto lo denominado invoker, y se encarga de invocar las operaciones de los diferentes objetos. El invocador puede ser tratado como parte de la aplicación cliente. Los objetos que ofrecen los servicios para procesar solicitudes se denominan objetos receiver (receptores).
  • Mediador, Intermediario, negociador (Mediator): En general, una aplicación orientada a objetos consiste de un conjunto de objetos que interactúan con el fin de proveer un servicio. Esta interacción puede ser directa (punto a punto). Cuando el número de objetos incrementa, este tipo de interacción puede conducir a una compleja maraña de referencias entre objetos, lo cual afecta la mantenibilidad de la aplicación. Además, la interacción directa entre muchos objetos, afecta el reuso debido a alto acoplamiento.
    En este caso, el patrón Mediator puede ser útil para diseñar una comunicación controlada y coordinada entre grupos de objetos, eliminando la necesidad de una comunicación directa entre objetos.
  • Recuerdo (Memento): El estado de un objeto se define como los valores de sus propiedades o atributos en un determinado momento. El patrón memento es útil para diseñar un mecanismo para capturar y almacenar el estado de un objeto, y posteriormente, cuando se requiera, regresar a su estado previo. Esto se asemeja a una operación de deshacer. El patrón memento puede ser útil para cumplir este propósito sin exponer la estructura interna de los objetos.
  • Observador (Observer): El patrón Observer es útil para diseñar un modelo de comunicación consistente entre un conjunto de objetos dependientes y un objeto del que dichos objetos dependen. Esto permite que los objetos dependientes tengan su estado sincronizado con el objeto del cual dependen. El conjunto de objetos dependientes se les llama observadores (observers) y el objeto del que ellos dependen se le llama sujeto (subject).
  • Interpretador, Intérprete, Traductor (Interpreter): En general, los lenguajes son construidos de un conjunto de reglas de gramaticales. Diferentes instrucciones pueden ser construidas mediante reglas gramaticales. En ocasiones una aplicación puede necesitar procesar ocurrencias de solicitudes similares que son combinaciones de un conjunto de reglas gramaticales. Estas solicitudes son distintas pero son similares en el sentido que están compuestas de las mismas reglas gramaticales. Un simple ejemplo de este orden debería ser el conjunto de diferentes expresiones gramaticales enviadas a una programa calculador. Aunque cada expresión es diferente, todas ellas están construidas usando las mismas reglas que conforman la gramática del lenguaje de expresiones aritméticas.
  • Estado (State): El patrón State es útil en el diseño de la estructura eficiente de una clase, donde una instancia puede tener muchos estados y exhibir diferentes comportamientos. En otras palabras, es útil cuando el comportamiento de un objeto sea influenciado por su estado actual. En el patrón State, a la clase que exhibe diferentes comportamientos, es referida como el Contexto de la clase.
  • Estrategia (Strategy): El patrón estrategia es útil cuando hay un conjunto de algoritmos relacionados y un objeto cliente que necesita dinámicamente elegir uno de esos algoritmos y adaptarlos a las necesidades actuales. El patrón estrategia sugiere mantener la implementación de cada algoritmo en clases separadas. Cada algoritmo encapsulado en una clase separada es denominado una estrategia. Un objeto que usa el objeto estrategia es denominado objeto contexto.
  • Objeto Nulo (Null Object): El término null se refiere a un objeto no existente. El patrón Null Object se aplica cuando un cliente espera el uso de diferentes subclases de una jerarquía para ejecutar un comportamiento y hacer referencia a esas subclases como objetos. En ocasiones, puede ser posible que una instancia de una subclase no está disponible cuando el cliente la esperaba. En este caso el objeto cliente recibe un objeto null. Cuando un objeto null es retornado, el cliente no puede invocar los métodos del objeto real. Por lo tanto, el cliente requiere verificar y asegurarse que el objeto no sea null antes de invocar sus métodos. En caso de null, el cliente debe programar algún comportamiento o no hacer nada.
  • Método Plantilla (Template Method): El patrón Template Method es uno de los más simples y más frecuentemente utilizados en apliciones orientadas a objetos. El patrón Template Method puede ser utilizado en situaciones cuando hay un algoritmo, donde algunos de los pasos pueden ser implementados de múltiples maneras. En tales escenarios, el patrón sugiere mantener el diseño del algoritmo en un método separado denominado template method dentro de una clase, la cual es denominada como clase template, excluyendo las implementaciones específicas de las porciones variantes (pasos que pueden ser implementados en múltiples maneras) del algoritmo a diferentes subclases de esta clase.
  • Objeto Autenticador (Object Authenticator): También conocido como Protection Proxy. En general, los objetos en una aplicación interactúan unos con otros para ofrecer una funcionalidad completa. La mayoría de los objetos están generalmente accesibles a todos los objetos de la aplicación. A veces, puede ser necesario restringir la accesibilidad de un objeto solamente a un conjunto limitado de objetos basados en sus derechos de acceso. Cuando un objeto cliente trata de acceder a dicho objeto, el objeto cliente está dando acceso a los servicios provistos por el objeto solamente si el cliente puede suministrar la credenciales de autenticación apropiadas. En tales casos, un objeto aparte puede ser diseñado con la responsabilidad de verificar los privilegios de acceso de diferentes objetos cliente. En otras palabras, cada cliente debe autenticarse satisfactoriamente con el objeto designado para acceder a la funcionalidad del objeto actual. A este objeto designado se le conoce como objeto autenticador (object authenticator).
  • Registro de Atributos Común (Common Attribute Registry): En general, los objetos en una aplicación se diseñan para llevar a cabo tareas bien definidas y datos relacionados una responsabilidad bien definida. En una aplicación estos objetos interactúan unos con otros para proveer una funcionalidad en conjunto. Durante tales interacciones, instancias de diferentes clases pueden necesitar acceder a un mismo conjunto de datos o atributos. Por ejemplo, diferentes objetos de negocio en una aplicación con frecuencia utilizan la misma cadena de conexión a la base de datos. Estos atributos comunes no son siempre de solo lectura. Consideremos el ejemplo de una aplicación que opera en modo local y remoto. Mientras la aplicación esté operando en modo remoto, si un objeto de la aplicación detecta problemas en la comunicación con el servidor remoto, inmediatamente informa a todos los objeto de la aplicación para que tomen acciones apropiadas para cambiarse al modo de operación local. La información del servidor remoto actual es relevante y común a todos los objetos de la aplicación. Los objetos de la aplicación leen y actualizan este tipo de información común. El registro de atributos común (Common Attribute Registry – CAR) es un objeto que se diseña exclusivamente para manejar un conjunto de datos comunes o atributos en una aplicación. 
 
 
 

PATRONES DE DISEÑO COLECCIONALES

  • Objeto Compuesto (Composite): Utilizado para construir objetos complejos a partir de otros más simples, utilizando para ello la composición recursiva y una estructura de árbol.
  • Iterador (Iterator): El patrón Iterator permite a objetos cliente acceder al contenido de un contenedor de manera secuencial, sin tener conocimiento acerca de la representación interna de su contenido. El término contenedor, se define como una colección de datos u objetos. Los objetos con el contenedor a su vez podrían ser colecciones, por lo que es una colección de colecciones. El patrón Iterator permite a un objeto cliente recorrer los objetos de esa colección, sin conocer cómo se almacenan los datos internamente.

  • Peso Ligero (Flyweight): Elimina la redundancia o la reduce cuando tenemos gran cantidad de objetos con información idéntica.
  • Visitante (Visitor): El patrón Visitor es útil para diseñar una operación  a través de una colección heterogénea de objetos de una jerarquía de clases. El patrón Visitor permite a la operación, ser diseñada sin cambiar las clases de la jerarquía. Parar lograr esto, el patrón Visitor sugiere definir la operación en una clase separada, denominada visitor. Esta clase separa la operación de la colección de objetos. Por cada nueva operación a ser definida, un nueva clase visitor se debe crear. Por lo tanto, la operación a ser ejecutada a través de un conjunto de objetos, el visitor necesita una forma de acceder a los miembros públicos de estos objetos. Los requisitos pueden ser  abordados mediante el diseño de las siguientes dos ideas.
  •  

Fuentes: Libardo Pantoja Universidad del Cauca, http://msdn.microsoft.com/es-es/library/bb972240.aspx

No hay comentarios:

Publicar un comentario