Andrés Felipe Crespo García — 4151310014
UNIVERSIDAD DE CARTAGENA Facultad de Ingeniería
PROGRAMA DE INGENIERÍA DE SISTEMAS Programas de Educación Abierta y a Distancia
Cartagena D. T. y C. 28 de mayo de 2017
2
PATRONES DE DISEÑO
Andrés Felipe Crespo García — 4151310014
Profesor:
CARLOS CÁCERES OCHOA
UNIVERSIDAD DE CARTAGENA Facultad de Ingeniería
PROGRAMA DE INGENIERÍA DE SISTEMAS Programas de Educación Abierta y a Distancia
Cartagena D. T. y C. 28 de mayo de 2017
3
“Nunca consideres el estudio como una
obligación, sino como una oportunidad para
penetrar en el bello y maravilloso mundo del
saber”
Albert Einstein físico y judío alemán del siglo XIX y XX (nació el 14 de marzo de 1879 y murió el 18 de abril de 1955) conocido principalmente por el
4
Contenido
Contexto ... ¡Error! Marcador no definido. Entregar ... ¡Error! Marcador no definido. Lógica del sistema de Bienestar Universitario — Universidad de Cartagena ... ¡Error! Marcador no definido.
Requerimientos ... ¡Error! Marcador no definido. Requerimientos funcionales ... ¡Error! Marcador no definido. Requerimientos no funcionales ... ¡Error! Marcador no definido. Lista de actores ... ¡Error! Marcador no definido. Perfiles de usuario ... ¡Error! Marcador no definido. Perfil: Administrador del sistema de información ... ¡Error! Marcador no definido. Perfil: Funcionario auxiliar ... ¡Error! Marcador no definido. Perfil: Asistentes ... ¡Error! Marcador no definido. Perfil: Invitado ... ¡Error! Marcador no definido. Perfil: Bienestar Universitario ... ¡Error! Marcador no definido. Tabla de tipos de requerimiento ... ¡Error! Marcador no definido. Diagramas de casos de usos... ¡Error! Marcador no definido.
5
Patrones de diseño
Los patrones de diseño son la base para la búsqueda de soluciones a problemas comunes en el desarrollo de software y otros ámbitos referentes al diseño de interacción o interfaces.
Un patrón de diseño resulta ser una solución a un problema de diseño. Para que una solución sea considerada un patrón debe poseer ciertas características. Una de ellas es que debe haber comprobado su efectividad resolviendo problemas similares en ocasiones anteriores. Otra es que debe ser reutilizable, lo que significa que es aplicable a diferentes problemas de diseño en distintas circunstancias.
Los patrones de diseño tienen como objetivo proporcionar catálogos de elementos reusables en el diseño de sistemas software, evitar la reiteración en la búsqueda de soluciones a problemas ya conocidos y solucionados anteriormente, formalizar un vocabulario común entre diseñadores, estandarizar el modo en que se realiza el diseño, facilitar el aprendizaje de las nuevas generaciones de diseñadores condensando conocimiento ya existente.
De igual manera estos no imponen ciertas alternativas de diseño frente a otras, no eliminar la creatividad inherente al proceso de diseño.
No es obligatorio utilizar los patrones, solo es aconsejable en el caso de tener el mismo problema o similar que soluciona el patrón, siempre teniendo en cuenta que en un caso particular puede no ser aplicable. “Abusar o forzar el uso de los patrones puede ser un error”.
Se suele categorizar a los patrones de diseño con respecto a tres características de los mismos, como son:
Según la escala o nivel de abstracción:
o Patrones de arquitectura: Aquellos que expresan un esquema organizativo estructural fundamental para sistemas de software.
6 o Patrones de diseño: Aquellos que expresan esquemas para definir estructuras de diseño (o sus relaciones) con las que construir sistemas de software.
o Dialectos: Patrones de bajo nivel específicos para un lenguaje de programación o entorno concreto.
Además, también es importante reseñar el concepto de “anti patrón de diseño”, que con forma semejante a la de un patrón, intenta prevenir contra errores comunes de diseño en el software. La idea de los anti patrones es dar a conocer los problemas que acarrean ciertos diseños muy frecuentes, para intentar evitar que diferentes sistemas acaben una y otra vez en el mismo callejón sin salida por haber cometido los mismos errores. Además de los patrones ya vistos actualmente existen otros patrones como el de interacción, que son patrones que nos permiten el diseño de interfaces web.
Los patrones tienen estructuras o plantillas de patrones, estas plantillas se usan más o menos estandarizadas, de forma que se expresen uniformemente y puedan constituir efectivamente un medio de comunicación uniforme entre diseñadores. Varios autores eminentes en esta área han propuesto plantillas ligeramente distintas, si bien la mayoría definen los mismos conceptos básicos.
Algunos de los patrones de diseño que existen son:
o Abstract Factory. Proporciona una interfaz para crear familias de objetos o que dependen entre sí, sin especificar sus clases concretas.
o Builder. Separa la construcción de un objeto complejo de su representación, de forma que el mismo proceso de construcción pueda crear diferentes representaciones.
o Factory Method. Define una interfaz para crear un objeto, pero deja que sean las subclases quienes decidan qué clase instanciar. Permite que una clase delegue en sus subclases la creación de objetos.
7 o Prototype. Especifica los tipos de objetos a crear por medio de una instancia
prototípica, y crear nuevos objetos copiando este prototipo.
o Singleton. Garantiza que una clase sólo tenga una instancia, y proporciona un punto de acceso global a ella.
8
1. Abstract Factory
El patrón Abstract Factory proporciona una forma de encapsular un grupo de fábricas individuales que tienen un tema común sin especificar sus clases concretas. En el uso normal, el software cliente crea una implementación concreta de la fábrica abstracta y luego utiliza la interfaz genérica de la fábrica para crear los objetos concretos que forman parte del software en cuestión. El cliente no sabe (o cuida) qué objetos concretos obtiene de cada una de estas fábricas internas, ya que utiliza sólo las interfaces genéricas de sus productos.
Este patrón separa los detalles de la implementación de un conjunto de objetos de su uso general y se basa en la composición del objeto, ya que la creación del objeto se implementa en los métodos expuestos en la interfaz de fábrica.
Una fábrica es la ubicación de una clase concreta en el código en el que se construyen los objetos. La intención de emplear el patrón es aislar la creación de objetos de su uso y crear familias de objetos relacionados sin tener que depender de sus clases concretas. Esto permite que se introduzcan nuevos tipos derivados sin cambiar el código que utiliza la clase base.
El uso de este patrón permite intercambiar implementaciones concretas sin cambiar el código que las usa, incluso en tiempo de ejecución. Sin embargo, el empleo de este patrón, como con patrones de diseño similares, puede resultar en complejidad innecesaria y trabajo adicional en la escritura inicial del código. Además, niveles más altos de separación y abstracción pueden resultar en sistemas que son más difíciles de depurar y mantener.
Este patrón se puede aplicar cuando:
Un sistema debe ser independiente de cómo sus objetos son creados.
Un sistema debe ser 'configurado' con una cierta familia de productos.
9 El patrón Abstract Factory tiene las características de brindar flexibilidad al aislar a las clases concretas, facilita cambiar las familias de productos, y para agregar nuevos productos se deben modificar tanto las fabricas abstractas como las concretas.
Este patrón determina el tipo concreto de objeto a crear, y es aquí donde el objeto se crea realmente. Sin embargo, la fábrica sólo devuelve un puntero abstracto al objeto concreto creado.
Esto aísla el código cliente de la creación de objetos haciendo que los clientes pidan a un objeto de fábrica que cree un objeto del tipo abstracto deseado y que devuelva un puntero abstracto al objeto.
Como la fábrica sólo devuelve un puntero abstracto, el código de cliente (que solicitó el objeto desde la fábrica) no sabe (y no se carga) el tipo concreto del objeto que acaba de crearse.
El código de cliente no tiene ningún conocimiento del tipo concreto, no necesitando incluir ningún archivo de cabecera o declaraciones de clase relacionadas con él. El código de cliente sólo se ocupa del tipo abstracto. De hecho, los objetos de un tipo concreto son creados por la fábrica, pero el código cliente sólo accede a dichos objetos a través de su interfaz abstracta.
La adición de nuevos tipos concretos se realiza modificando el código de cliente para usar una fábrica diferente, una modificación que normalmente es una línea en un archivo. La fábrica diferente crea objetos de un tipo de concreto diferente, pero aún devuelve un puntero del mismo tipo abstracto que antes, aislando así el código del cliente del cambio. Esto es mucho más fácil que modificar el código de cliente para instanciar un nuevo tipo, lo que requeriría cambiar cada ubicación en el código donde se crea un nuevo objeto (así como asegurarse de que todas las ubicaciones de código tienen conocimiento del nuevo tipo de concreto, Incluyendo, por ejemplo, un archivo de encabezado concreto de la clase). Si todos los objetos de fábrica se almacenan globalmente en un objeto singleton y todo el código de cliente pasa a
10 través del singleton para acceder a la fábrica adecuada para la creación de objetos, cambiar fábricas es tan fácil como cambiar el objeto singleton.
11
2. Observer
Este es un patrón de diseño que define una dependencia del tipo uno-a-muchos entre objetos, de manera que cuando uno de los objetos cambia su estado, notifica este cambio a todos los dependientes. Se trata de un patrón de comportamiento (existen de 3 tipos: Creación, Estructurales y de Comportamiento), es decir, está relacionado con algoritmos de funcionamiento y asignación de responsabilidades a clases y objetos. Los patrones de comportamiento describen no solamente estructuras de relación entre objetos o clases sino también esquemas de comunicación entre ellos y se pueden clasificar en función de que trabajen con clases (Método Plantilla) u objetos (Cadena de Responsabilidad, Comando, Iterador, Recuerdo, Observador, Estado, Estrategia, Visitante).
La variación de la encapsulación es la base de muchos patrones de comportamiento, por lo que cuando un aspecto de un programa cambia frecuentemente, estos patrones definen un objeto que encapsula dicho aspecto. Los patrones definen una clase abstracta que describe la encapsulación del objeto. Este patrón también se conoce como el patrón de publicación-inscripción o modelo-patrón. Estos nombres sugieren las ideas básicas del patrón, que son: el objeto de datos, que se le puede llamar Sujeto a partir de ahora, contiene atributos mediante los cuales cualquier objeto Observador o vista se puede suscribir a él pasándole una referencia a sí mismo.
El patrón Observer es la clave del patrón de arquitectura Modelo Vista Controlador (MVC).
Típicamente, el patrón Observer se implementa con el "sujeto" (que está siendo "observado") que forma parte del objeto cuyo cambio de estado se está observando, para ser comunicado a los observadores cuando ocurre. Este tipo de implementación se considera "estrechamente acoplado", obligando tanto a los observadores como al sujeto a estar conscientes entre sí y tener acceso a sus partes internas, creando posibles problemas de escalabilidad, velocidad, recuperación y
12 mantenimiento de mensajes (también llamado evento o notificación pérdida), la falta de flexibilidad en la dispersión condicional y el posible obstáculo a las medidas de seguridad deseadas. En algunas implementaciones (no de sondeo) del patrón publicar-suscribirse (también llamado patrón pub-sub), esto se resuelve creando un servidor de "cola de mensajes" dedicado y, a veces, un objeto extra de "manejador de mensajes", como etapas añadidas Entre el observador y el objeto observado que se está comprobando el estado, desacoplando así los componentes del software. En estos casos, los observadores con el patrón de observador, "suscribiéndose a ciertos mensajes", conocen sólo el mensaje esperado (o no, en algunos casos), pero no saben nada sobre el remitente del mensaje Remitente no puede saber nada acerca de los receptores. Otras implementaciones del patrón publicar-suscribirse, que logran un efecto similar de notificación y comunicación a las partes interesadas, no usan el patrón del observador en conjunto.
13
3. Delegate
En la ingeniería de software, el patrón de delegación es un patrón de diseño en programación orientada a objetos que permite que la composición del objeto consiga la misma reutilización de código que la herencia.
En Delegate, un objeto gestiona una solicitud delegando en un segundo objeto (el delegado). El delegado es un objeto auxiliar, pero con el contexto original. Con el nivel de idioma de apoyo a la delegación, esto se hace implícitamente por tener auto en el delegado se refieren al objeto original (de envío), no al delegado (objeto receptor). En el patrón de delegado, esto se realiza en lugar de pasar explícitamente el objeto original al delegado, como un argumento a un método. Obsérvese que la "delegación" se suele utilizar de forma poco clara para referirse al concepto distinto de reenvío, en el que el objeto emisor simplemente utiliza el miembro correspondiente en el objeto receptor, evaluado en el contexto del objeto receptor y no del objeto original.
La delegación es una manera de hacer que la composición sea tan poderosa para la reutilización como la herencia. En la delegación, dos objetos están involucrados en el manejo de una solicitud: un objeto receptor delega las operaciones a su delegado. Esto es análogo a las subclases que aplazan las solicitudes a las clases progenitoras. Pero con la herencia, una operación heredada siempre puede referirse al objeto receptor a través de la variable de este miembro en C ++ y self en Smalltalk. Para lograr el mismo efecto con delegación, el receptor pasa al delegado para permitir que la operación delegada se refiera al receptor.
14
4. Prototype
El patrón de diseño Prototype sirve para crear clonaciones de objetos (instancias de clases) a fin de no acarrear todo lo que lleva la creación del mismo desde cero, parámetros, métodos a ejecutar, etc. Hay que tener en cuenta que clonar un objeto es mucho más rápido que crearlo.
El patrón de prototipo es un patrón de diseño creacional en el desarrollo de software. Se utiliza cuando el tipo de objetos a crear está determinado por una instancia prototípica, que se clona para producir nuevos objetos. Este patrón se utiliza para:
Evitar las subclases de un creador de objetos en la aplicación cliente, como hace el patrón abstracto de fábrica.
Evitar el coste inherente de crear un nuevo objeto de la manera estándar (por ejemplo, utilizando la palabra clave 'nuevo') cuando es prohibitivamente costoso para una aplicación dada.
Para implementar el patrón, se debe declarar una clase base abstracta que especifique un método virtual clone puro. Cualquier clase que necesite una capacidad de "constructor polimórfico" se deriva de la clase base abstracta e implementa la operación clone.
El cliente, en lugar de escribir código que invoca al operador "nuevo" en un nombre de clase codificado, llama al método clone en el prototipo, llama a un método de fábrica con un parámetro que designa la determinada clase concreta derivada deseada o invoca el Clone a través de algún mecanismo proporcionado por otro patrón de diseño.
La división mitótica de una célula - que resulta en dos células idénticas - es un ejemplo de un prototipo que desempeña un papel activo en la copia de sí mismo y, por tanto, demuestra el patrón Prototype. Cuando una célula se divide, dos células de idéntico genotipo resultan. En otras palabras, la célula se clona a sí misma.
15
5. Singleton
El Singleton es quizás el más sencillo de los patrones. Es también uno de los patrones más conocidos y utilizados. Su propósito es asegurar que sólo exista una instancia de una clase.
El patrón Singleton garantiza que una clase sólo tenga una instancia y proporciona un punto de acceso global a ésta instancia. Este define una operación Instancia que permite que los clientes accedan a su única instancia. Instancia es una operación de clase.
El Singleton suele ser usado cuando deba existir exactamente una instancia de una clase y ésta deba ser accesible a los clientes desde un punto de acceso conocido. La única instancia debería ser extensible mediante herencia y los clientes deberían ser capaces de utilizar una instancia extendida sin modificar su código.
Como consecuencias tiene acceso controlado a la única instancia. Puede tener un control estricto sobre cómo y cuándo acceden los clientes a la instancia, espacio de nombres reducido. El patrón Singleton es una mejora sobre las variables globales. Permite el refinamiento de operaciones y la representación. Se puede crear una subclase de Singleton, permite un número variable de instancias. El patrón hace que sea fácil cambiar de opinión y permitir más de una instancia de la clase Singleton.
A primera vista, uno puede pensar que pueden utilizarse clases con miembros estáticos para el mismo fin. Sin embargo, los resultados no son los mismos, ya que en este caso la responsabilidad de tener una única instancia recae en el cliente de la clase. El patrón Singleton hace que la clase sea responsable de su única instancia, quitando así este problema a los clientes.
Adicionalmente, si todos los métodos de esta clase son estáticos, éstos no pueden ser extendidos, desaprovechando así las capacidades polimórficas que nos proveen los entornos orientados a objetos.