Bloque III. Tema 9. Diseño de programas. Diagramas estructurados. Análisis de transformación y de transacción. Cohesión y acoplamiento

Índice de contenido

Bloque III. Tema 9. Diseño de programas. Diagramas estructurados. Análisis de transformación y de transacción. Cohesión y acoplamiento        1

Patrones de Diseño        1

Patrones de Creación        2

Creación: Abstract Factory        2

Creación: Builder        2

Creación: Factory Method        2

Creación: Object Pool        2

Creación: Prototype        2

Creación: Singleton        2

Patrones Estructurales        2

Estructural: Adapter        3

Estructural: Bridge        3

Estructural: Composite        3

Estructural: Decorator        3

Estructural: Façade        3

Estructural: Flyweight        3

Estructural: Private Class Data        3

Estructural: Proxy        3

Patrones de comportamiento        3

Comportamiento: Chain of Responsibility        3

Comportamiento: Command        4

Comportamiento: Interpreter        4

Comportamiento: Iterator        4

Comportamiento: Mediator        4

Comportamiento: Memento        4

Diagrama de estructura        4

Análisis de Transformación        5

Análisis de Transacción        5

Cohesión y acoplamiento        6

Acoplamiento        6

Cohesión        6

Patrones de Diseño

http://sourcemaking.com/design_patterns

Patrones de Creación

Son patrones de diseño para tratar con mecanismos de creación de objetos, tratando de crearlos de una manera que sea apropiada a cada situación. La forma básica de creación de objetos podría resultar en problemas de diseño o de complejidad añadida.

Algunas veces los patrones de creación son competidores: hay casos donde o bien se usa Prototype o bien Abstract Factory. Otras veces se complementan: Abstract Factory podría guardar un conjunto de Prototypes y Builder puede usar alguno de los demás patrones para implementar qué componentes se construyen.

Creación: Abstract Factory

Crea una instancia de algunas familias de clases. Proporciona una interfaz para crear familias de objetos relacionados o dependientes sin especificar las clases concretas. Sirve cuando queremos hacer aplicaciones portables y la clase que terminamos creando dependa de la plataforma.

Creación: Builder

En la creación de un objeto complejo, separar la construcción de su representación de manera que el mismo proceso de construcción puede crear diferentes representaciones. Sirve para abstraer el proceso de creación de un objeto que está compuesto de otros objetos, de manera que se haga la misma llamada para construir los componentes, pero internamente puedan crear cosas distintas dependiendo de las necesidades.

Creación: Factory Method

Define una interfaz para crear un objeto, pero dejar que las subclases decidan qué clase instanciar. Deja a la clase delegar la instanciación en las subclases. Define un “constructor virtual”. La “clase instanciada” define simplemente placeholders para métodos pero deja los detalles a las subclases. Es útil para frameworks (como Java Media Framework) que deben funcionar en una gran variedad de arquitecturas/sistemas operativos.

Creación: Object Pool

Para rendimiento. Es más efectivo en situaciones donde el coste de iniciar una instancia es alto, la tasa de instanciación es alta y el número de instanciaciones en uso es bajo. Típico de pool de conexiones a bases de datos.

Creación: Prototype

Especificar los objetos a crear usando una instancia prototipo ya existente y crear los objetos nuevos copiando esa instancia. Es la programación orientada a prototipos. Para solucionar el problema de que la aplicación “cablea” la clase del objeto a crear en cada llamada a “new”.

Creación: Singleton

Asegurarse de que una clase tiene una sola instancia y proporcionar un punto de acceso global a ella.

Patrones Estructurales

Son patrones que facilitan el diseño identificando una forma simple de realizar relaciones entre entidades.

Estructural: Adapter

Convierte la interfaz de una clase en otra que el cliente espera.

Estructural: Bridge

Desacopla una abstracción de su implementación para que las dos puedan variar de forma independiente. Ir más allá de la encapsulación, al aislamiento. Se usa cuando la interfaz y lo que hace -implementación- varía mucho. A menudo se confunde con el Adapter. Es como tener dos niveles de abstracción.

Estructural: Composite

Es un patrón de particionamiento. Describe un grupo de objetos que van a ser tratados de la misma manera que una instancia simple de un objeto. La intención es componer objetos en estructuras arbóreas para representar jerarquías. Se utiliza cuando se trabaja con estructuras de datos en árbol. Un composite en OOP es un grupo de objetos similares que exhiben similar funcionalidad.

Estructural: Decorator

Añadir responsabilidades a un objeto de forma dinámica. Es una alternativa a las subclases para extender funcionalidad. Añadir comportamiento a un objeto en tiempo de ejecución.

Estructural: Façade

Proporciona una interfaz unificada a un conjunto de interfaces en un subsistema. Define una interfaz de más alto nivel. Si cada piso es una interfaz, la fachada es la interfaz de todos los pisos.

Estructural: Flyweight

Un objeto de peso ligero minimiza el uso de memoria compartiendo tanto como pueda con otros objetos similares. En lugar de tener una colección grande de objetos grandes que tienen mucho en común, se divide el objeto en dos piezas: la parte compartida y la parte propia. Y se saca la parte compartida.

Estructural: Private Class Data

Controla el acceso de escritura a los atributos de la clase. Separa los datos de los métodos que los usan. Encapsula los datos de inicialización de la clase. Vamos, hacer que los datos de clase no sean visibles.

Estructural: Proxy

Hay objetos que consumen muchos recursos y no quieres instanciarlos realmente hasta que se necesiten, en su lugar se instancia el proxy. Pero al primer uso se instanciará el objeto real.

Patrones de comportamiento

Son patrones que identifican patrones de comportamiento comunes entre objetos y los realizan. Haciéndolo, estos patrones aumentan la flexibilidad al realizar esta comunicación.

Comportamiento: Chain of Responsibility

Evitar el acoplamiento del que envía una petición al su receptor cuando se le da a más de un objeto la posibilidad de manejar la petición. Encadenar los objetos receptores y pasar la petición a lo largo de la cadena hasta que un objeto se haga cargo.

El problema es cuando hay un número variable de objetos “manejadores” o “elementos de procesado” o “nodos” y una serie de peticiones que deben ser manejadas. Se me ocurre que esto puede ser cuando tenemos una aplicación web y queremos mapear las peticiones a manejadores.

Se necesita procesar las peticiones de forma eficiente sin cablear las relaciones entre los manejadores o la precedencia entre ellos, o realizar mapeos de petición-a-manejador.

La solución es encapsular los elementos de procesamiento en una tubería y dejar que los clientes suelten la petición a la entrada y se olviden.

Comportamiento: Command

Encapsular una petición dentro de un objeto. Desacopla el objeto que invoca la operación del que sabe como ejecutarla.

Comportamiento: Interpreter

Dado un lenguaje, definir una representación de su gramática junto con un intérprete que usa esa representación para interpretar sentencias en ese lenguaje.

Comportamiento: Iterator

Acceder secuencialmente a los miembros de una colección.

Comportamiento: Mediator

Define un objeto que encapsula como un conjunto de objetos interacciona. Promociona el acoplamiento débil evitando que unos objetos hagan referencia a otros explícitamente.

En Unix tenemos usuarios y grupos. Si decidimos modelar esto, podríamos decidir enlazar grupos a usuarios y usuarios a grupos. Entonces cuando vienen los cambios en asignaciones de usuarios a grupos y grupos a usuarios, todas las instancias son afectadas.

Una solución alternativa sería introducir “un nivel adicional de indirección”, coger el mapeo de usuarios a grupos y grupos a usuarios y hacerlo una abstracción en sí mismo. Imaginemos el desastre de tener en cada usuario un array de grupos y en cada grupo un array de usuarios. En su lugar, los usuarios no harán referencia a los grupos ni los grupos a los usuarios y sacamos fuera esa relación.

Comportamiento: Memento

Sin violar la encapsulación, capturar y externalizar -hacer una foto- del estado interno de un objeto de manera que pueda ser devuelto a ese estado más tarde. Por ejemplo en operaciones de deshacer, rehacer o rollback.

Diagrama de estructura

El DFD es más declarativo, éste se comunicará con éste otro y accederá a tal o cual almacén de datos, pero ahí se queda. Para concretar hay que decir qué información se intercambia, con quien, en qué orden, etc. y en esa concreción lo que estamos haciendo es montar el Diagrama de estructura.

Representar la estructura modular del sistema o de un componente del mismo y definir los parámetros de entrada y salida de cada uno de los módulos.

Para su realización se partirá del modelo de procesos obtenido como resultado de la aplicación de la técnica de diagrama de flujo de datos. Elementos:

Estructuras del diagrama:

Dependiendo de la estructura inicial del DFD sobre el que se va a realizar el diseño, existen dos estrategias para obtener el diagrama de estructura. El uso de una de las dos estrategias no implica que la otra no se utilice, eso dependerá de las características de los procesos representados en el DFD. Estas estrategias son:

Análisis de Transformación

Es un conjunto de pasos que permite obtener, a partir de un DFD con características de transformación, la estructura de diseño de alto nivel del sistema. Un DFD con características de transformación es aquél en el que se pueden distinguir:

Los datos que necesita el sistema se recogen por los módulos que se encuentran en las ramas de la izquierda, de modo que los datos que se intercambian en esa zona serán ascendentes. En las ramas centrales habrá movimiento de información compartida, tanto ascendente como descendente.

Análisis de Transacción

Se aplica cuando en un DFD existe un proceso que en función del flujo de llegada, determina la elección de uno o más flujos de información.

Se denomina centro de transacción al proceso desde el que parten los posibles caminos de información.

Un DFD de estas características se ve porque hay un punto donde se decide por qué transacción continuar.

Y finalmente hay que evaluar el diseño en términos de cohesión y acoplamiento.

Cohesión y acoplamiento

Referencias:

El diseño estructurado persigue elaborar algoritmos que cumplan con la propiedad de modularidad. Dado un problema se busca dividir el programa en módulos. Para evaluar o determinar cómo de bueno es un diseño estructurado se utilizan los conceptos de acoplamiento y cohesión. Están muy relacionados entre sí y difícilmente se puede variar uno de ellos sin afectar al otro. No son medidas que se puedan cuantificar numéricamente, son más bien magnitudes cualitativas. También se tienen en consideración los conceptos de fan-in y fan-out.

Acoplamiento

El grado de interdependencia que hay entre los distintos módulos de un programa y depende del número de parámetros que se intercambian (grado de acoplamiento); lo deseable es que sea lo menor posible. Los niveles de acoplamiento de menor (deseable) a mayor son:

Cohesión

Se define como la medida de fuerza o relación funcional existente entre las sentencias o grupos de sentencias de un mismo módulo. Un módulo cohesionado ejecutará una única tarea sencilla interaccionando muy poco o nada con el resto de módulos del programa. Se persigue que los módulos tengan una alta cohesión.

Podemos encontrar 7 tipos de cohesión de la más deseable (mayor cohesión) a la menos deseable (menor cohesión):

Un buen diseño debe ir orientado a que los módulos realicen una función sencilla e independiente de las demás (máxima cohesión) y que la dependencia con otros módulos sea mínima (acoplamiento mínimo), lo cual facilita el mantenimiento del diseño.