2020 DSI Patrones de Diseño
2020 DSI Patrones de Diseño
Patrones de Diseño
Judith Meles
Cecilia Massano
Laura Covaro
Elizabeth Jeinson
Patrones de Diseño
◎ Refinan un subsistema o componente de un
sistema software.
◎ Describen una estructura a la cual muchas
veces recurrimos para resolver problemas
de diseño.
◎ Patrones de escala media.
◎ No afectan a la arquitectura de un sistema
◎ No dependen del lenguaje de
implementación.
◎ Permiten resolver problemas complejos y
direccionan la cooperación efectiva entre
componentes
Patrones vs. Idiomas
◉ La diferencia es el alcance.
◉ En general, tanto los patrones de diseño como
los idiomas describen soluciones a problemas de
diseño recurrentes.
◉ En el patrón de diseño, tanto el problema como la
solución son lo suficientemente genéricos como para
ser independientes del lenguaje de programación.
◉ Un idioma, por el contrario, es un patrón de bajo nivel
que es específico a un lenguaje de programación.
Patrones
◎ Describen un problema recurrente y
una solución.
◎ Cada patrón nombra, explica, evalúa
un diseño recurrente en sistemas
OO.
◎ Elementos principales:
◉ Nombre
◉ Problema
◉ Solución: Descripción abstracta
◉ Consecuencias
El nombre
◎ Se debe poder describir con una o
dos palabras un problema, sus
soluciones y la consecuencia.
◉ Nominar un patrón incrementa los
vocabularios de diseño
◉ Nos permite diseñar con abstracción
de un nivel más alto
El problema
◎ Describe cuando se puede aplicar el patrón.
Explica el problema y su contexto.
◉ Puede ser problemas específicos tales como
representar los algoritmos con objetos
◉ Puede describir clases o estructuras de objetos que
son sintomáticos de un diseño flexible
◉ Puede incluir una lista de condiciones que se
tienen que satisfacer antes de aplicar el patrón
La Solución
◎ Describe los elementos que forman el
diseño, sus relaciones, responsabilidades, y
cooperaciones.
◉ La solución no describe ningún diseño concreto
◉ Un patrón es una plantilla para muchas
situaciones diferentes
◉ Un patrón dispone la descripción abstracta de un
problema de diseño y cómo se resuelve con
elementos (clases y objetos) generales
Las consecuencias
◎ Los buenos resultados e inconveniencia de
aplicar el patrón
◎ Consecuencias
◉ ¿Cómo alcanza el patrón sus objetivos?, ¿Cuáles son los compromisos y
resultados de usar el patrón?, Alternativas, Costes y Beneficios
◎ Implementación
◉ Técnicas, heurísticas y consejos para la implementación
◉ ¿Hay cuestiones dependientes del lenguaje?
◎ Ejemplo de Código
◎ Usos conocidos
◎ Patrones relacionados
¿Cómo seleccionar un patrón?
◎ Considera de que forma los patrones resuelven
problemas de diseño
◎ Lee la sección que describe el propósito de cada
patrón
◎ Estudia las interrelaciones entre patrones
◎ Analiza patrones con el mismo propósito
◎ Examina las causas de rediseñar
◎ Considera que debería ser variable en tu diseño
¿Cómo usar un patrón?
◎ Lee el patrón, todos sus apartados.
◎ Obtenga una visión global.
◎ Estudia la Estructura, Participantes y Colaboraciones
◎ Mira el ejemplo de código
◎ Asocia a cada participante del patrón un elemento software
de tu aplicación.
◎ Implementa las clases y métodos
relacionados con el patrón.
¿A qué ayudan los patrones?
Diseñar
para el
Favorecer cambio
reutilización
Especificar
Especificar implementación
interfaces
Determinar
granularidad
Encontrar
objetos
¿A qué ayudan los patrones?
◎ Encontrar los objetos
◉ Tarea difícil
◉ Debemos considerar: encapsulamiento, flexibilidad,
dependencias, reutilización, extensibilidad, rendimiento,…
◉ Clases del análisis vs. Clases del diseño
◉ Clases del diseño no tienen contrapartida en el dominio
Fabricación Pura
◉ Clases del diseño son claves para hacer el sistema más
flexible.
¿A qué ayudan los patrones?
◎ Determinar granularidad de los objetos
◉ Facade, Flyweight, Builder, Visitor,..
◎ Especificar interfaces
◉ Memento, Decorator, Proxy,..
◎ Especificar implementación de clases
◉ Muchos patrones dependen de la distinción entre herencia
de implementación y herencia de interfaces
◉ Observer, State, Chain of Responsability,…
¿A qué ayudan los patrones?
◎ Especificar implementación de clases
“programar hacia la interfaz, no hacia la implementación”
◎ Favorecer la reutilización
“Favorecer la composición sobre la herencia de clases”
Herencia y composición trabajan juntas
“Se suele abusar de la herencia. Los diseños suelen ser
más reutilizables si dependen de la composición”.
¿A qué ayudan los patrones?
◎ La clave para la reutilización es anticiparse a los nuevos
requisitos y cambios, de modo que los sistemas
evolucionen de forma adecuada.
◎ Cada patrón permite que algunos aspectos de la estructura
del sistema puedan cambiar independientemente de otros
aspectos.
◎ Facilitan reuso interno, extensibilidad y mantenimiento.
Tipos de patrones de diseño
(Gamma)
◎ Patrones de Creación
◎ Patrones de Estructura
◎ Patrones de Comportamiento
Patrones de Creación
◎ Abstraen el proceso de creación de objetos.
◎ Ayudan a crear sistemas independientes de cómo los objetos son
creados, compuestos y representados.
◎ Dos tipos:
◉ Clase: usa herencia para variar la clase que es instanciada.
◉ Objeto: delega instanciación a otro objeto.
Patrones de Creación
Patrones de Estructura
Patrones de Comportamiento
¿A qué ayudan los patrones?
◎ Se encapsula:
◉ qué clases concretas usa el sistema
◉ cómo se crean las instancias de esas clases
◎ El sistema conoce las clases abstractas
◎ Flexibilidad en qué se crea, quién lo crea, cómo se crea y
cuándo se crea.
Patrones de Creación
Patrones de Estructura
Patrones de Comportamiento
¿A qué ayudan los patrones?
◎ Abstract Factory (Fábrica Abstracta): Proporciona una interfaz para crear familias de objetos
relacionados o que dependen entre sí, sin especificar sus clases concretas.
◎ Factory Method (Método de Fabricación): Define una interfaz para crear un objeto, pero deja
que las subclases deciden que clase instanciar. Delega en las subclases la creación de objetos.
◎ Singleton (Único): Garantiza que una clase tenga una única instancia y proporciona un punto
de acceso global a ella.
◎ Builder (Constructor): 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.
◎ Prototype (Prototipo):Especifica los tipos de objeto a crear por medio de una instancia
prototípica, y crea nuevos objetos copiando de este prototipo.
Patrones de Creación
Patrones de Estructura
Patrones de Comportamiento
Patrones de Estructura
◎ Determinan cómo combinar objetos y clases para definir
estructuras complejas.
◉ Comunicar dos clases incompatibles,
◉ Añadir funcionalidad a objetos
Patrones de Creación
Patrones de Estructura
Patrones de Comportamiento
Patrones de Estructura
◎ Adapter (Adaptador): Convierte la interfaz de una clase en otra distinta que es la que esperan los
clientes. Permite que cooperen las clases que de otra manera tendrían interfaces
incompatibles.
◎ Bridge (Puente): Desacopla una abstracción de su implementación, de manera que ambas puedan variar de
forma independiente.
◎ Composite (Compuesto):Combina objetos en estructuras de árbol para representar jerarquías de todo-parte.
Permite que los clientes traten de manera uniforme a los objetos individuales y a los compuestos.
◎ Decorator (Decorador): Añade dinámicamente nuevas responsabilidades a un objeto,
proporcionando una alternativa flexible a la herencia para extender funcionalidad.
◎ Façade (Fachada): Proporciona una interfaz unificada para un conjunto de interfaces de un subsistema.
Define una interfaz de alto nivel que hace que el subsistema sea más fácil de utilizar.
◎ Flyweight (Peso Ligero): Usa el comportamiento para permitir un gran número de objetos de
granularidad fina de forma eficiente.
◎ Proxy (Apoderado): Proporciona un sustituto o representante de otro objeto para controlar el acceso a éste.
Patrones de Creación
Patrones de Estructura
Patrones de Comportamiento
Patrones de Comportamiento
◎ Se ocupan de los algoritmos y reparto de responsabilidades.
◎ Describen los patrones de comunicación entre objetos y clases.
◎ Podremos definir abstracciones de algoritmos (Template Method)
◎ Cooperaciones entre objetos para realizar tareas complejas, reduciendo las
dependencias entre objetos (Iterator, Observer, etc.)
◎ Asociar comportamiento a objetos e invocar su ejecución (Command, Strategy,
etc.)
Patrones de Creación
Patrones de Estructura
Patrones de Comportamiento
Patrones de Comportamiento
◎ Chain of Responsibility (Cadena de Responsabilidad): Evitar acoplar el emisor de una petición a su
receptor, al dar a más de un objeto la posibilidad de responder a la petición. Crea una cadena
con los objetos receptores y pasa la petición a través de la cadena hasta que ésta sea tratada por
algún objeto.
◎ Command (Orden): Encapsula una petición en un objeto, permitiendo así parametrizar a los clientes con
distintas peticiones, encolar o llevar un registro de las peticiones y poder deshacer las operaciones.
◎ Interpreter (Intérprete): Define para un lenguaje dado, una representación de su gramática junto
con un intérprete que usa dicha representación para interpretar sentencias del lenguaje.
◎ Iterator (Iterador): Proporciona un modo de acceder secuencialmente a los elementos de un
objeto agregado sin exponer su representación interna.
◎ Mediator (Mediador): Define un objeto que encapsula cómo interactúan los objetos. Promueve un
bajo acoplamiento al evitar que los objetos se refieran uno a otros explícitamente, y permite
variar la interacción entre ellos de forma independiente.
Patrones de Creación
Patrones de Estructura
Patrones de Comportamiento
Patrones de Comportamiento (cont.)
◎ Memento (Recuerdo): Representa y externaliza el estado interno de un objeto sin violar el
encapsulamiento, de forma que éste puede volver a dicho estado más tarde.
◎ Observer (Observador): Define una dependencia de uno a muchos entre objetos, de forma que cuando un
objeto cambie de estado se notifica y se actualizan automáticamente todos los objetos que dependen de
él.
◎ State (Estado): Permite que un objeto modifique su comportamiento cada vez que cambie su estado
interno. Parecerá que cambia la clase del objeto.
◎ Strategy (Estrategia): Define una familia de algoritmos, encapsula cada uno de ellos y los hace
intercambiables. Permite que un algoritmo varíe independientemente de los clientes que lo usan.
◎ Template Method (Método Plantilla): Define en una operación el esqueleto de algún algoritmo, delegando
en las subclases algunos de sus pasos. Permite que las subclases redefinan ciertos pasos del algoritmo sin
cambiar su estructura.
◎ Visitor (Visitante): Representa una operación sobre los elementos de una estructura de objetos. Permite
definir una nueva operación sin cambiar las clases de los elementos sobre los que opera.
Patrones de Creación
Patrones de Estructura
Patrones de Comportamiento
Clasificación
Propósito
Creación Estructura Comportamiento
Interpreter
Ámbito Clase Factory Method Adapter
Template Method
Chain of Responsability
Objeto Abstract Factory Adapter Command
Builder Bridge Iterator
Prototype Composite Mediator
Singleton Decorator Memento
Facade Observer
Flyweight State
Proxy Strategy
Visitor
30
Caso de Estudio
Objetivo:
Dar soporte a los procesos de venta de artículos, cobranza, preparación y despacho
de los pedidos a través de las empresas de transporte contratadas, brindando
información vinculada a la gestión y a la toma de decisiones.
Alcances:
• Administrar artículos y kits de artículos con sus tipos y medios de soporte
• Administrar catálogos de artículos
• Gestionar pedidos en todo su ciclo de vida, incluida su preparación y envío,
notificando cambios de estados del pedido
31
Caso de Estudio
Alcances (continuación):
• Administrar clientes y las tarjetas de crédito con las que operan
• Administrar marcas de tarjetas de créditos
• Gestionar la cobranza por tarjeta de créditos
• Gestionar comentarios sobre artículos o pedidos
• Administrar empresas de transportes y sus puntos de distribución
• Administrar medios de transportes y formas de envío
• Administrar usuarios y la personalización de sus perfiles
• Administrar las ubicaciones geográficas y localizaciones
• Gestionar la entrega de pedidos y la devolución de pedidos no entregados
32
Caso de Estudio
Alcances (continuación):
• Administrar motivos de no entrega
• Brindar información sobre pedidos y su estado
• Brindar información sobre los despachos de pedidos por forma de envío y por
empresa de transporte
• Brindar información de ventas por cliente y por tipo de artículo
• Brindar información sobre frecuencia de compra por cliente y volumen de la
operación
• Brindar información sobre los artículos más vendidos
33
Caso de Estudio
No Contempla:
• Contratación y Pago a proveedores
• Contabilización de las transacciones
• Logística de distribución de los pedidos, está a cargo de las empresas de
transporte contratadas
• Gestión de Stock, sólo se descuenta del stock lo vendido.
34
Caso de Estudio
Reglas de Negocio (de la funcionalidad afectada a este taller)
• Costo de Envío: El precio de la entrega se determina para cada destino y varía
según el medio de transporte y la forma de envío.
• Opciones de Envío: Se dispone de 3 opciones de envío: un solo envío, los
mínimos posibles, y tan pronto como tenga los artículos.
• Único Catálogo Vigente: Sólo puede existir un único catálogo vigente.
• Kits de artículos: Los kits sólo se pueden armar con artículos del mismo tipo.
• Forma de Pago: La única forma de pago aceptada es tarjeta de crédito en un solo
pago.
35
Caso de Estudio
Reglas de Negocio (de la funcionalidad afectada a este taller)
• Notificación del Estado del Pedido: Se notificará al usuario en cada cambio de
estado que defina o afecte la fecha estimada de entrega
• Cobertura de Entrega de Pedidos: Sólo se distribuirán a aquellos destinos donde
alguna empresa de transporte tiene un Punto de Distribución.
• Empresa de Transporte Asignada: Existirá una única empresa de transporte activa
para un Destino, Medio de Transporte y Forma de Envío.
36
Caso de Estudio Venta Digital: Modelo de Dominio
State
State (Estado)
◎ Propósito
◉ Permite a un objeto cambiar su comportamiento cuando cambia su
estado. El objeto parece cambiar de clase.
◎ Motivación
◉ Una conexión TCP puede encontrarse en uno de varios estados, y
dependiendo del estado responderá de un modo diferente a los mensajes
de otros objetos para solicitudes tales como abrir, cerrar o establecer
conexión.
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
State (Estado)
C o n te xto + e s ta d o E s ta d o
s o lic it u d () o p e ra c io n ()
e s ta d o .o p e r a c io n ( )
E s ta d o C o n c r e to 1 E s ta d o C o n c r e to 2
o p e ra c io n () o p e ra c io n ()
State (Estado)
◎ Aplicabilidad
◉ El comportamiento del objeto depende de su estado, y
debe cambiar su comportamiento en tiempo de ejecución
dependiendo de su estado.
◉ Las operaciones tienen grandes estructuras CASE que
dependen del estado del objeto, que es representado por
uno o más constantes de tipo enumerado.
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
State (Estado)
◎ Consecuencias
◉ Coloca todo el comportamiento asociado a un estado
particular en una clase.
◉ Subclases vs. Sentencias CASE.
◉ Ayuda a evitar estados inconsistentes
◉ Transiciones de estado son más explícitas.
◉ Incrementa el número de objetos
○ Posible solución: Los objetos ESTADO pueden ser compartidos.
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Máquina de Estado de la Clase Pedido
stm DTE-Pedido
VEN-01-Agregar
artículo a carro de
compras /new() EnCarroDeCompras
VEN-05-Confirmar pedido
/confirmarPedido()
Confirmado
DES-09-Generar
VEN-02-Cancelar VEN-02-Cancelar remito /preparar()
pedido /cancelar() pedido /cancelar()
DES-09-Generar remito
/deshacerPreparacion()
VEN-02-Cancelar pedido
Cancelado
/cancelar() EnPreparacion DES-09-Generar remito
/preparar()
Despachado
DES-01-Importar estado del envío del
pedido [todos los artículos entregados]
/entregar()
Finalizado
Máquina de Estado de la Clase DetallePedido
stm DetallePedido
VEN-01-Agregar artículo a carro de
compras /new()
VEN-02-Cancelar
pedido /cancelar() Cancelado
PendienteDePreparacion
VEN-02-Cancelar
pedido /cancelar()
DES-09-Generar
remito /preparar()
DES-09-Generar remito
/deshacerPreparacion() VEN-02-Cancelar
pedido /cancelar()
EnPreparacion
DES-02-Cancelar remito
/cancelarPreparacion() EnDespacho
◎ Procedimiento
◉ El GestorPedido le pide al Pedido, que agregue un producto a la lista de los
productos que contiene el pedido.
◉ El Pedido delega la petición, en función de su estado actual a la instancia de
estado concreto que corresponda: EnCarroDeCompras.
◉ La Instancia de EstadoConcreto que corresponda resuelve la petición.
State: Aplicación
◎ Dinámica:
◎ Ventajas:
◉ Se eliminan las sentencias CASE utilizando Polimorfismo.
◉ Permite crecimiento en la variación de la lógica de negocio en función de los cambios de estado.
Strategy
Strategy/Policy (Estrategia)
◎ Propósito
◉ Define una familia de algoritmos, encapsula cada uno, y permite
intercambiarlos. Permite variar los algoritmos de forma
independiente a los clientes que los usan
◎ Motivación
◉ Existen muchos algoritmos para justificación de texto, ¿debe
implementarlo el cliente que lo necesita?
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Strategy
Estructura
C o n te xto + E s tr a te g ia E s tr a te g ia
Herencia E s tr a te g ia A E s tr a te g ia B
Strategy
Estructura
C o n te xto + IE s tr a te g ia IE s tr a te g ia
in t e rf a c e C o n t e x to ( ) a lg o rit m o In t e rfa c e ()
E s tr a te g ia A E s tr a te g ia B
Realización
Strategy
◎ Aplicabilidad
◉ Configurar una clase con uno de varios comportamientos
posibles.
◉ Se necesitan diferentes variantes de un algoritmo.
◉ Una clase define muchos comportamientos que aparecen
como sentencias CASE en sus métodos.
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Strategy
◎ Consecuencias
◉ Define una familia de algoritmos relacionados.
◉ Una alternativa a crear subclases de la clase Contexto.
◉ Elimina sentencias CASE
◉ El cliente puede elegir entre diferentes estrategias o
implementaciones: debe conocer detalles
◉ Se incrementa el número de objetos:
○ Solución: usar Flyweight
◉ State y Strategy son similares, cambia el Propósito
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Caso Liga de Fútbol – Realización de CU de Análisis del
class Vista Generar Diagramación del Campeonato
Caso de Uso Generar Diagramación del Campeonato
«control»
«entity» «entity»
«boundary» Ge storDiagram acionCam pe onato
Siste m aCam pe onato TipoCam pe onato
PantGe nDiagrCam pe onato camptoVigente :Campeonato
nombre nombre
txtSistCampeonato cantFechas
caracteristicas mesInicioSugerido
txtT ipoCampeonato cantPartidos
valorPartidoEmpatado esT uMesJuego()
txtFechaInicial fechaPrimerJornada
valorPartidoGanado
cmbClub datosPartidos getMesInicioJuego()
txtCantFechas datosFechas getNombre() getNombre()
grillaFechas getValorPartidoGanado()
buscarArbitros() 1
grillaPartidos calcularCantFechas()
buscarCampeonatoVigente()
calcularCantPartidos()
habilitarVentana() buscarClubesInscriptos()
mostrarFechas() buscarEstadoParaCampeonato() 1
mostrarFechasSugeridas() buscarRoles()
mostrarNombreCampeonato() determinarCantFechas() «entity»
mostrarPartidos() determinarCantPartidos() Cam pe onato
mostrarSistemaYT ipoCampeonato() calcularFechaDeJornadas() nombre
mostrarT ipoCampeonato() crearEstrategia() sistemaCampeonato :SistemaCampeonato
opcionGenerarDiagramacion() calcularClubesParaPartidosRestantes() tipoCampeonato :T ipoCampeonato
pedirConfirmacionDiagramacion() finCU() fechaCampeonato :FechaCampeonato
pedirHorarioPartido() generarDiagramacion() estadoActual :Estado
pedirIngresoPrimeraJornada() nuevaDiagramacion() estadoAnterior :Estado
pedirSeleccionArbitrosPorRol() obtenerFechaActual() fechaDeInicio
pedirSeleccionClubes() tomarArbitrosYRolPorPartido() fechaDeFin
tomarConfirmacionDiagramacion() tomarClubesPartido() fechaVtoPresExamen
tomarFechaPrimeraJornada() tomarConfirmacionDiag() inscripcion :InscripcionClub
tomarHoraPartido() tomarHoraPartido() puntosPartidoGanado
tomarSeleccionArbitro() tomarPrimeraJornada() puntosPartidoEmpatado
tomarSeleccionLocal() validarAsignacionArbitros()
validarClubesEnPartidos() actualizarPartidoAJugado()
tomarSeleccionRolArbitral()
verificarSistemaCampeonato() buscarFechasPendientes()
tomarSeleccionVisitante()
buscarEstadoParaPartido() calcularGoleadorCampeonato()
buscarEstadoParaFecha() calcularGoleadorFecha()
calcularT ablaPosicion()
cancelar()
«entity» getEstadoActual()
«entity» getEstadoAnterior()
RolArbitral
Estado getFechaCampeonato()
nombre 1 cuantasFechas()
«entity» nombre
getNombre() Arbitro descripcion cuantosPartidosPorFecha()
ambito estaDiagramadoCompleto()
1 apellido 0..1 estaEnCurso()
dni esAmbitoCampeonato() finalizar()
nombre esDiagramadoCompleto() getFechasPendientes()
fechaNacimiento esDiagramada() buscarPartidosPendientes()
«entity» 1 esPendJuego()
AsignacionArbitral getNombreCompleto() getPartidosPorFecha()
1 esAmbitoPartido() new()
rol :RolArbitral esAmbitoFecha() buscarJugadoresDelPartido()
arbitro :Arbitro reanudar()
0..1 1
fechaHoraAsignacion registrarDesempeñoJugadores()
getArbitro() registrarGoles()
getRol() registrarResultadoDelPartido()
new() suspender()
0..* tieneDiagramacion()
0..*
«entity» validarFechaCompleta()
Fe chaCam pe onato calcularClubesIncriptos()
estadoActual :Estado determinarCantFechas()
estadoAnterior :Estado determinarCantPartidos()
«entity»
fechaComienzo
Partido
numero
fechaInicio partido :Partido 0..*
1..*
horaInicio
crearPartido() «entity»
local :Club new() InscripcionClub
visitante :Club 0..1
actuacionJugador :ActuacionJugador cancha :Cancha
asignacion :AsignacionArbitral club :Club
estado :Estado ganadorPartidoVisitante detalleInscripcion :JugadorInscripto
ganadorPartidoLocal :Partido fechaInscripcion
ganadorPartidoVisitante :Partido ganadorPartidoLocal getDetalleInscripcion()
puntajeObtenidoVisitante esLaUltima()
0..1
puntajeObtenidoLocal getDatosJugadores()
«entity» cuantosJugadoresInscriptos()
crearAsignacionArbitros()
new() Club listarJugadorConExamenPend()
setEstado() nombre 0..* esDelCampeonato()
domicilio
inscripcion :InscripcionClub
0..1
buscarInscripcionCampeonato()
getNombreCanchaCampeonato()
estaInscriptoCampenato()
getNombre()
0..1
Caso Liga de Fútbol – Realización de CU de Análisis del
Caso de Uso Generar Diagramación del Campeonato
sd Generar Diagramacion del Campeonato Curso Normal
69: finCU()
62: generarDiagramacion() 6: esVigente()
59: buscarEstadoParaCampeonato()
56: buscarEstadoParaPartido()
53: buscarEstadoParaFecha() :Campeonato :Estado
52: validarAsignacionArbitros() 5: *estaVigente()
51: validarClubesEnPartidos()
42: buscarRoles()
40: buscarArbitros() :
39: calcularClubesParaPartidosRestantes() TipoCampeonato
49: tomarConfirmacionDiagramacion() 50: tomarConfirmacionDiag()
30: calcularFechaDeJornadas()
11: getNombre()
46: tomarSeleccionRolArbitral() 47: tomarArbitrosYRolPorPartido() 29: verificarSistemaCampeonato() 63: diagramar()
45: tomarSeleccionArbitro() 22: determinarCantPartidos() 23: determinarCantPartidos() 24: calcularCantPartidos()
38: tomarClubesPartido()
18: determinarCantFechas() 19: determinarCantFechas() 20: calcularCantFechas()
37: tomarSeleccionVisitante()
34: tomarHoraPartido() 14: buscarClubesInscriptos() 15: buscarClubesInscriptos() 9: getNombre()
36: tomarSeleccionLocal() 2: habilitarVentana() 70: setEstado()
4: buscarCampeonatoVigente() 10: getTipoCampeonato()
33: tomarHoraPartido() 28: tomarPrimeraJornada() 8: getSistemaCampeonato() :
27: tomarFechaPrimeraJornada() 3: nuevaDiagramacion() 7: getNombre() SistemaCampeonato
1: opcionGenerarDiagramacion()
12: mostrarNombreCampeonato() : vigente : 65: crearPartido()
: 64: *new()
13: mostrarSistemaYTipoCampeonato() GestorDiagramacionCampeonato Campeonato
:Administrador PantGenDiagrCampeonato
del Campeonato 21: mostrarFechas()
25: mostrarPartidos() 16: *getNombreClub()
26: pedirIngresoPrimeraJornada() :
31: mostrarFechasSugeridas() FechaCampeonato
32: pedirHorarioPartido() 43: *getNombre()
35: pedirSeleccionClubes()
:
44: pedirSeleccionArbitrosPorRol() InscripcionClub
66: *new()
48: pedirConfirmacionDiagramacion()
17: getNombre()
67: crearAsignacionArbitros()
41: *getNombreCompleto()
54: *esAmbitoFecha()
:RolArbitral
55: *esDiagramada() 68: *new()
| :Club :
57: *esAmbitoPartido() :Partido
AsignacionArbitral
58: *esPendJuego() :Arbitro
60: *esAmbitoCampeonato()
61: *esDiagramadoCompleto()
:Estado
Strategy: Aplicación
class Strategy
«entity»
SistemaCampeonato
- caracteristicas IEstrategiaSistemaDeCampeonatos
- nombre + calcularCantFechas(club: Club[]): Integer
- valorPartidoEmpatado + calcularCantPartidos(cantFechas: Integer, club: Club[]): Integer
- valorPartidoGanado + contarClubes(club: Club[]): Integer
+ calcularCantFechas(): void
+ calcularCantPartidos(): void
+ getNombre(): String
+ getValorPartidoGanado(): Integer
1
sistemaCampeonato
EstrategiaEliminatorias EstrategiaTodosContraTodos
+ calcularCantFechas(club: Club[]): Integer + calcularCantFechas(club: Club[]): Integer
+ calcularCantPartidos(cantFechas: Integer, club: Club[]): Integer + calcularCantPartidos(canFechas: Integer, club: Club[]): Integer
+ contarClubes(club: Club[]): Integer + contarClubes(club: Club[]): Integer
+ new(nombreEstrategia: String): EstrategiaEliminatorias + new(nombreEstrategia: String): EstrategiaTodosContraTodos
«entity»
Campeonato
- estadoActual: Estado
- estadoAnterior: Estado
- fechaCampeonato: FechaCampeonato «control»
- fechaDeFin GestorDiagramacionCampeonato Las clases sombreadas en verde se
- fechaDeInicio - camptoVigente: Campeonato agregan y la sombreada en naranja se
- fechaVtoPresExamen - cantFechas modifica al implementar el patrón.
- inscripcion: InscripcionClub - cantPartidos
- nombre - datosFechas
- puntosPartidoEmpatado - datosPartidos
- puntosPartidoGanado - fechaPrimerJornada
- sistemaCampeonato: SistemaCampeonato
- tipoCampeonato: TipoCampeonato + buscarEstadoParaFecha(): void
+ buscarEstadoParaPartido(): void
+ calcularClubesIncriptos(): void + crearEstrategia(): IEstrategiaSistemaCampeonatos
+ determinarCantFechas(): void + determinarCantFechas(): int
+ determinarCantPartidos(): void + determinarCantPartidos(): int
Estructura
+ enCurso(): void
+ getSistemaCampeonato()
+ setEstado(): void
sd Strategy
Strategy: :
GestorDiagramacionCampeonato
:Campeonato :
SistemaCampeonato
...
Aplicación
calcularCantFechas(club : Club[]){
Método cantidadFechas=Club.Size-1;
determinarCantFechas(): int
18 del }
determinarCantFechas(club: Club[]): int
análisis.
calcularCantFechas(club: Club[]): int
crearEstrategia(): IEstrategiaSistemaDeCampeonatos
crearEstrategia(): IEstrategiaSistemaDeCampeonatos
ClaseAbstracta
metodoPlantilla()
....
operacionPrimitiva1() operacionPrimitiva1()
Estructura operacionPrimitiva2() ...
operacionPrimitiva2()
.....
ClaseConcreta
operacionPrimitiva1()
operacionPrimitiva2()
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Template Method
◎ Aplicabilidad
◉ Implementar las partes fijas de un algoritmo y dejar que las
subclases implementen el comportamiento que puede variar.
◉ Cuando el comportamiento común entre varias subclases debe ser
factorizado y localizado en una superclase común.
◉ Controlar extensiones de las subclases: algoritmos con puntos de
extensión
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Template Method
◎ Consecuencias
◉ Técnica fundamental para la reutilización: factorizar comportamiento común en
librerías de clases
◉ Estructura de control invertida conocida como “Principio de Hollywood”: “No nos
llames, nosotros te llamaremos”.
◉ Un método plantilla (template) invoca a los siguientes tipos de métodos:
○ operaciones concretas en la subclase concreta o en clientes
○ operaciones concretas en la clase abstracta
○ operaciones abstractas (primitivas)
○ métodos factoría (uso combinado con el Factory Method)
○ métodos hook que proporcionan comportamiento por defecto que se
implementa en la clase abstracta y que las subclases pueden utilizar o ignorar
en función de lo que necesiten. También puede estar vacío.
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Template Method
◎ Implementación
◉ Minimizar el número de métodos que es necesario redefinir
en las subclases.
◉ Nombrar a los métodos que se deben redefinir añadiéndole
cierto prefijo, p.e. “do”.
◉ En C++, métodos a redefinir son protegidos y virtuales, el
método plantilla no será virtual.
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Template class Template Method
«control»
Method: +
GestorCatalogo
•
El Template Method (método plantilla)
es el método "mostrarInfoProducto()".
Los métodos "mostrarInfoEspecífica()" y
"conocerTraducciones()" son los
Aplicación métodos abstractos variables que cada
subclase concreta implementará de
manera diferente.
«entity» • Los métodos "getTitulo()",
Articulo "conocerProductora()" y
- codigo: String "conocerIdiomaOriginal()" son los
- titulo: String métodos de enganche (hook).
- productora: Productora[]
- idiomaOriginal: Idioma[]
+ getCodigo() : String
Estructura +
+
+
getIdiomaOriginal() : Idioma
getTitulo() : String
conocerProductora() : String[] -
«entity»
Pelicula
calificacion: Calificacion
+ conocerIdiomaOriginal() : String[] - rubro: Rubro
+ mostrarInfoProducto() : String[] - idiomaSubtitulo: Idioma
+ mostrarInfoEspecífica() : String[]
+ conocerTraducciones() : String[] + getCalificacion() : Calificacion
+ getIdiomaSubtitulo() : Idioma[]
+ mostrarInfoEspecífica() : String[]
1..* 1 + conocerTraducciones() : String[][]
«entity» «entity» 0..*
Productora Idioma
1 1
- nombre: String - nombre: String
«entity» «entity»
+ getNombre() : String + getNombre() : String Calificacion Rubro
- nombre: String - nombre: String
+ getNombre() : String + getNombre() : String
Template Method: Aplicación
◎ Participantes
Method:
:GestorCatalogo :Pelicula :Productora :Idioma :Calificacion :Rubro
Aplicación conocerArticulo(Articulo) :String[]
mostrarInfoProducto() :String[]
getTitulo() :String
conocerProductora() :String
*getNombre() :String
conocerIdiomaOriginal() :String
getNombre() :String
◎ Procedimiento
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
90
80
Motivación 2tr
4tr Vistas
70
60
50 Este
40
30
Oeste
Norte 1tr
20
10
3tr
0
1er trim. 2do trim. 3er trim. 4to trim.
S u je to C o n c r e to
e s t a d o S u je t o O b s e r v a d o r C o n c r e to
e s t a d o O b s e rva d o r
s e t E s t a d o()
g e t E s t a d o() + th e S u je to C o n c r e t o a c t u a liz a rE s t a d o ()
e s ta d o O b s e r v a d o r = S u je to
- > g e tE s ta d o ( )
Observer Estructura
P a r a to d o s lo s O e n
o b s e rv a d o re s {O ->
u p d a te ( ) }
IS u je to
Realización
IO b s e r v a d o r
s e p a ra r(o b s e rv a d o r)
a d ju n ta r ( o b s e r v a d o r ) 1 1 ..*
a c tu a liza r ( s u je to )
n o tific a r ( )
S u je to C o n c r e to
O b s e r v a d o r C o n c r e to
e s ta d o S u je to
e s ta d o O b s e r v a d o r
s e tE s ta d o ( )
+ th e S u je to C o n c r e to a c tu a liza r E s ta d o ( )
g e tE s ta d o ( )
e s ta d o O b s e r v a d o r = S u je to
- > g e tE s ta d o ( )
Colaboración
: O tr a : S u je to o1 : o2 :
O b s e r va d o r O b s e rv a d o r
1 . se t E s ta d o ( )
1 .1 . n o t ific a r( )
1 .1 .1 . a c tu a liza r ( )
1 .1 .2 . a ctu a liza r ( )
Observer
◎ Aplicabilidad
◉ Cuando un cambio de estado en un objeto requiere
cambios en otros objetos, y no sabe sobre cuántos objetos
debe aplicarse el cambio.
◉ Cuando un objeto debe ser capaz de notificar algo a otros
objetos, sin hacer asunciones sobre quiénes son estos
objetos.
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Observer
◎ Consecuencias
◉ Permite modificar independientemente subjects y observers.
◉ Acoplamiento abstracto y mínimo entre Subject y Observer:
○ pueden reutilizarse por separado
○ observers pueden añadirse sin modificar el subject
○ Subject no necesita conocer las clases concretas de
Observers
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Observer
◎ Consecuencias
◉ Soporte para comunicación de tipo broadcast:
○ el subject no especifica al receptor concreto de la notificación
○ es posible añadir y eliminar observers en cualquier instante.
◉ Actualizaciones inesperadas
◉ Interfaz de Observer simple requiere que los observers
tengan que deducir el ítem cambiado
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Observer
◎ Cuando la semántica de las actualizaciones es compleja, puede ser necesario
que un objeto mantenga esas relaciones, GestorDeCambios.
◎ El propósito del GestorDeCambios es minimizar el trabajo necesario para lograr
que los observadores reflejen el cambio en su sujeto.
◎ GestorDeCambios tiene las siguientes responsabilidades:
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Observer: Aplicación
◎ Consecuencias
◉ Reusabilidad: Al separar el Sujeto de sus Observadores se permite
reutilizar sujetos y observadores independientemente.
◉ Flexibilidad: Se pueden agregar y quitar observadores en cualquier
momento sin afectar al sujeto ni ha otros observadores, ya que el Sujeto
siempre ejecuta el método notificar() para todos los observadores
existentes.
◉ Disminuye el Acoplamiento: el sujeto conoce a sus observadores en las
clases Madre, lo cual reduce el acoplamiento entre las clases
instanciables, ya que la relación es abstracta.
◉ Es posible asegurar la consistencia entre Sujeto y Observadores
aplicando el patrón Template Method, haciendo que al finalizar la
actualización del Sujeto se llame al método notificar(), evitando el riesgo
de llamarlo cuando aún no se ha producido la actualización.
Observer: Aplicación
Estructura con Gestor de Cambios
S u je to G e s to r D e C a m b io s
c o rre s p o n d e n c ia S u je t o O b s e rva d o r
O b s e rv a d o r
+ g e s to r D e C a m b io s + O b s e rv a d o r
(fr o m L o g i c a l V i e w )
s e p a ra r()
s u s c rib ir(s u je t o , o b s e rva d o r) 1..*
a d ju n t a r()
n o t ific a r() 1 ..*
+ s u je to n o t ific a r() a c t u a liz a r( s u je t o )
s e p a ra r(s u je t o , o b s e rva d o r)
G e s to rD e C a m b i o s -
> n o ti fi c a r() G e s to r D e C a m b io s S im p le G e s to r D e C a m b io s G D A
G e s to rD e C a m b i
o s -> s u s c ri b i r
(th i s , o )
N o tifica r: p a r a to d o s e n N o tific a r : m a r c a r to d o s lo s
s u j e to s o b s e r v a d o r e s a a c tu a liza r
p a ra to d o o e n s . o b s e r v a d o re s a c tu a liza r to d o s lo s
o - > a c tu a l iza r ( s ) o b s e rv a d o re s m a rc a d o s
Herencia
Observer: Aplicación
Estructura con Gestor de Cambios
Sujeto IGestorDeCambios
+IGestorDeCambios Observador
correspondenciaSujetoObservador +Observador
separar(observador) (from Logical View)
adjuntar(observador) 1 1.. *
suscribir(sujeto, observador)
notificar() +Sujeto notificar() actualizar(sujeto)
1..* separar(sujeto, observador)
GestorDeCambio
s -> notificar()
GestorDeCambios
-> suscribir(this, o) GestorDeCambiosSimple GestorDeCambiosGDA
Realización
Observer: Aplicación
class Observer-Pull
«interface»
ISujetoNoficacionPedido
«private» «interface»
+ observador :IObserverNotificacionPedido[] IObserverNotificacionPedido
0..* + enviarMail(p :Pedido) :void «boundary»
+ notificar() :void
NotificacionEnvioParcial
+ quitar(o :IObserverNotificacionPedido) :void
+ suscribir(o :IObserverNotificacionPedido) :void + enviarMail(p :Pedido) :void
- generarMail() :void
«control»
«control» GestorPedido
GestorEnvio - numeroPedido :int «boundary»
+ notificar() :void + notificar() :void NotificacionConfirmacionPedido
+ quitar(o :IObserverNotificacionPedido) :void + quitar(o :IObserverNotificacionPedido) :void
+ suscribir(o :IObserverNotificacionPedido) :void + enviarMail(p :Pedido) :void
+ suscribir(o :IObserverNotificacionPedido) :void - generarMail() :void
+ tomarConfirmacion() :void + new() :void
-pedido
«boundary»
«entity» NotificacionDespachoRetrasado
Pedido + enviarMail(p :Pedido) :void
«boundary»
PantallaCrearPedido - detalle :DetallePedido[] - generarMail() :void
- estado :EstadoPedido
+ pedirConfirmacionPedido() :void - numero :int
+
+
confirmarPedido() :void
getNumero() :int
Estructura (PULL)
+ listarArticulosPedido() :String[][]
+ quitarArticulo()
+ setEstado(nuevo :EstadoPedido) :void
Observer: Aplicación
◎ Participantes
◉ Sujeto [ISujetoNotificacionPedido]: Proporciona una interfaz para notificar
a sus Observadores de sus modificaciones.
◉ Observador [IObserverNotificacionPedido]: Proporciona una interfaz para
actualizar los objetos que deben enterarse de cambios en el Sujeto.
◉ SujetoConcreto [GestorEnvio y GestorPedido]: Almacena el estado (valor
de los atributos) que importan a los Observadores y notifica a los mismos
sobre cambios ocurridos.
◉ ObservadorConcreto [NotificacionConfirmacionPedido,
NotificacionDespachoRetrasado, NotificacionEnvioParcial]
Observer : Aplicación Dinámica
sd Observer-Pull
«state»
:EnCarroDeCompra El GestorPedido crea un objeto que implementa
:PantallaCrearPedido :GestorPedido :Pedido la InterfazNotificacion para notificar vía e-mail al
cliente la confirmación del pedido, y lo suscribe.
tomarConfirmacion()
Luego el observador concreto de tipo
confirmarPedido() Notificación Confirmación Pedido, cuando lo
desea va al pedido a requerir su nuevo estado
confirmarPedido() (sus datos).
new() «state»
:Confirmado
setEstado(nuevo :
EstadoPedido)
new()
:NotificacionConfirmacionPedido
suscribir(o :IObserverNotificacionPedido)
notificar()
enviarMail(p :Pedido)
generarMail()
getNumero() :int
listarArticulosPedido() :String[]
Observer: Aplicación
◎ Procedimiento
◉ Cuando se produce un cambio en el estado del pedido, el se deberá notificar
a todos los suscriptos (InterfazNotificacion), para que realicen la notificación
correspondiente en función del estado del Pedido.
◉ El GestorPedido corrobora que el estado del pedido se ha modificado, por lo
que llama a su método notificar() e informa a las Notificaciones.
◉ En función del estado del pedido se analiza que Notificación corresponde que
ejecute el método enviarMail() declarado en la interfaz
IObserverNotificacionPedido.
◉ El método generarMail() que se implementa en cada Notificación concreta
que corresponda, pide las actualizaciones que corresponden, en este caso al
objeto Pedido.
Observer: Aplicación
class Observer-Push
«interface»
ISujetoNoficacionPedido
«interface»
«private» IObserverNotificacionPedido
+ observador :IObserverNotificacionPedido[]
0..* + actualizar(nroPed :int, fecha :Date, email :String, detalle :String[], texto :String) :void
+ notificar() :void
+ quitar(o :IObserverNotificacionPedido) :void
+ suscribir(o :IObserverNotificacionPedido) :void
«boundary»
«control» NotificacionDespachoRetrasado
GestorEnvio
«control»
+ actualizar(nroPed :int, fecha :Date, email :String, detalle :String[], texto :String) :void
GestorPedido + notificar() :void - generarMail() :void
- numeroPedido :int + quitar(o :IObserverNotificacionPedido) :void
+ suscribir(o :IObserverNotificacionPedido) :void
+ notificar() :void
+ quitar(o :IObserverNotificacionPedido) :void
+ suscribir(o :IObserverNotificacionPedido) :void «boundary»
+ tomarConfirmacion() :void NotificacionEnvioParcial
«boundary» + actualizar(nroPed :int, fecha :Date, email :String, detalle :String[], texto :String) :void
-pedido PantallaCrearPedido - generarMail() :void
+ confirmarPedido() :void
«entity»
«boundary»
Pedido
NotificacionConfirmacionPedido
- detalle :DetallePedido[]
- estado :EstadoPedido + actualizar(nroPed :int, fecha :Date, email :String, detalle :String[], texto :String) :void
+ confirmarPedido() :void
+ setEstado(nuevo :EstadoPedido) :void
Estructura (Push) - generarMail() :void
+ new() :void
Observer : Aplicación
sd Observer-Push
«state»
:EnCarroDeCompra
:PantallaCrearPedido :GestorPedido :Pedido
tomarConfirmacion()
confirmarPedido() Dinámica
confirmarPedido()
new() «state»
:Confirmado
setEstado(nuevo :EstadoPedido)
new()
:NotificacionConfirmacionPedido
suscribir(o :IObserverNotificacionPedido)
notificar()
actualizar(nroPed :int, fecha :Date, email :String, detalle :String[], texto :String)
generarMail()
Tras producirse el cambio de estado del Pedido, se notifica y se envía datos forzosamente a los
observadores suscriptos al sujeto GestorPedido. Luego los Observadores disponen de esos
datos para realizar sus operaciones.
Observer: Aplicación
◎ Participantes
◉ Sujeto [ISujetoNotificacionPedido]: Proporciona una interfaz para notificar a sus
Observadores de sus modificaciones.
◉ Observador [IObserverNotificacionPedido]: Proporciona una interfaz para
actualizar los objetos que deben enterarse de cambios en el Sujeto.
◉ SujetoConcreto [GestorEnvio y GestorPedido]: Almacena el estado (valor de los
atributos) que importan a los Observadores y notifica a los mismos sobre cambios
ocurridos.
◉ ObservadorConcreto [NotificacionConfirmacionPedido,
NotificacionDespachoRetrasado, NotificacionEnvioParcial]: Debe mantener su
estado consistente al del sujeto concreto, para lo cual implementa el método
actualizar().
Observer: Aplicación
◎ Procedimiento
Notificación de que el pedido ha sido registrado
◉ El GestorPedido manda la confirmación al Pedido, el Pedido delega esa
confirmación al estado que se encuentra Carrito.
◉ El Carrito crea el nuevo estado Confirmado y se lo devuelve al Pedido.
◉ El GestorPedido debe notificar el cambio de estado y llama a su método
notificar() y actualiza las pantallas de Notificacion.
◉ En función del estado del pedido se analiza que Notificacion corresponde
que ejecute el método actualizar() declarado en la interfaz
IObserverNotificacionPedido.
◉ La pantalla NotificacionConfirmacionPedido, es quien debe hacer algo en
este caso, el método actualizar() llama al método concreto generarMail()
de la Notificacion concreta que corresponda.
Builder
Builder (Constructor)
◎ Propósito
◉ Separa la construcción de un objeto complejo de su
representación, así que el mismo proceso de construcción
puede crear diferentes representaciones.
◎ Motivación
◉ Un traductor de documentos RTF a otros formatos. ¿Es
posible añadir una nueva conversión sin modificar el
traductor?
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Builder (Constructor)
D ir e c to r + b u il d e r B uilde r
Herencia
c o n s tr uir() c o n s t ru irP a rt e ()
B u ild e r C o n c r e to
P a r a t o d o o b je to e n la P r o d u c to
e s t r u c tu r a c o n s tr ui rP a r te ( )
g e tR e s u lt a d o ()
{ b u i ld e r .c o n s tru ir P a r te }
D ir e c to r + b u ild e r B u ilder
c o n s tr uir()
c o n s tr uirP a rt e () Realización
P a r a t o d o o b je to e n la
e s t r u c tu r a B u ild e r C o n c r e to
{ b u i ld e r .c o n s tru ir P a r te } P r o d u c to
c o n s tr ui rP a r te ( )
g e tR e s u lt a d o ()
Builder (Constructor)
◎ Aplicabilidad
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Builder (Constructor)
◎ Consecuencias
◉ Permite cambiar la representación interna del producto.
◉ Separa el código de la representación del código para la
construcción.
◉ Proporciona un control fino del proceso de
construcción.
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Builder (Constructor)
◎ Implementación
:GestorPublicacionCatalogo
Dinámica:
publicarCatalogoResumen()
new() «constructor»
ConstructorCatalogoResumenWeb
construirProducto()
new()
:PantallaCatalogoResumenWeb
El método construirImagen(...) se construirSeccion(sec :String[])
implementa vacío, ya que el producto *agregarSeccion(s :String)
ResumenWeb no muestra la imagen del
artículo.
construirArticulo(art :String[][])
*agregarArticulo(a :
String[][])
construirImagen(img :String[])
obtenerProducto() :PantallaCatalogoResumenWeb
publicar()
101
Propósito
Define una interfaz para la creación de objetos delegando en las
subclases la decisión de qué clase instanciar.
La intención del Factory Method es tener una clase a la cual
delegar la responsabilidad de la creación de los objetos, para
no decidir en tiempo de compilación que clase instanciará, si
no que delegará esta responsabilidad al Factory confiando en
que este le regresará la clase adecuada para trabajar.
Ámbito
De Clase
Factory Method 106
Aplicabilidad
Implementación
1. Haga que todos los productos sigan la misma interfaz. Esta interfaz
debe declarar métodos que tengan sentido en cada producto.
Implementación (Continuación)
Estructura - Realización
Patrón de Creación Patrón de Estructura Patrón de Comportamiento
«interface» «interface»
IProducto ICreador
+ metodoDeFabricacion()
+ unaOperacion()
ProductoConcreto CreadorConcreto
«crea»
return new()
+ metodoDeFabricacion() productoConcreto
Patrón de Creación Patrón de Estructura Patrón de Comportamiento
Estructura - Herencia
Factory Method
110
Factory Method 111
Aplicación
Venta
Digital
Estructura
Análisis – CU
Registrar
Artículo
Factory Method 113
Aplicación Venta Digital
Dinámica Análisis – CU Registrar Artículo
Patrón de Creación Patrón de Estructura Patrón de Comportamiento
Factory Method 114
Patrón de Creación Patrón de Estructura Patrón de Comportamiento
Aplicación
Venta
Digital
Estructura
Diseño – CU
Registrar
Artículo
Factory Method 115
Aplicación Venta Digital
Dinámica Diseño – CU Registrar Artículo
Patrón de Creación Patrón de Estructura Patrón de Comportamiento
Factory Method 116
• Producto [Articulo]: Declara una interfaz de los objetos que crea el método
de Fabricación.
• ProductoConcreto [Libro, JuegoVideo, Pelicula, Musica]: Implementa
las operaciones declaradas en la interfaz de producto.
• Creador [IGestorArticulo]: Declara el método de fabricación, el cual
devuelve un objeto de tipo Articulo.
• También puede definir una implementación predeterminada del método de
fabricación que devuelva un objeto del producto concreto (herencia).
• Puede llamar al método de fabricación para crear un objeto Articulo.
• Creador Concreto [GestorLibro, GestorPelicula, GestorMusica,
GestorJuegoVideo]: Redefine el método de fabricación para devolver una
instancia de un producto concreto.
Factory Method
Ventajas
Patrón de Creación Patrón de Estructura Patrón de Comportamiento
Desventajas
Patrón de Creación Patrón de Estructura Patrón de Comportamiento
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Composite
Estructura
C o m p o n e n te
C l ie n te o p e ra c io n ()
a ñ a d i r ( C o m p o n e n te )
e l i m i n a r ( C o m p o n e n te )
o b te n e r H i j o ( )
Herencia h ijo s
C o m p u e s to
H o ja
o p e ra c io n ()
o p e ra c io n () a ñ a d i r ( C o m p o n e n te )
e l i m i n a r ( C o m p o n e n te )
o b te n e r H i j o ( )
Composite
IComponente
Cliente
operacion()
añadir(Componente)
eliminar(Componente)
obtenerHijo() hijos
Estructura
Realización Compuesto
Hoja
operacion()
operacion() añadir(Componente)
eliminar(Componente)
obtenerHijo()
Composite
◎ Aplicabilidad
◉ Se quiere representar jerarquías todo/parte
◉ Se quiere que los clientes ignoren la diferencia entre
objetos compuestos y los objetos individuales que los
forman.
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Composite
◎ Consecuencias
◉ Jerarquía con clases que modelan objetos primitivos y objetos
compuestos, que permite composición recursiva.
◉ Clientes pueden tratar objetos primitivos y compuestos de modo
uniforme.
◉ Es fácil añadir nuevos tipos de componentes.
◉ No se puede confiar al sistema de tipos que asegure que un objeto
compuesto sólo contendrá objetos de ciertas clases, necesidad de
comprobaciones en tiempo de ejecución.
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Composite
◎ Implementación
Composite -
GestorCatalogo
catalogo :IComponenteCatalogo
+
+
+
agregarComponente(IComponenteCatalogo) :void
getDescripcionJerarquia() :String[]
obtenerHijo() :IComponenteCatalogo
+ crearIterador(Object[]) :IIterador + quitarComponente(IComponenteCatalogo) :void 1..*
+ listarCatalogo() :String[][]
CompuestoCatalogo
- agrupaArtDestacados :boolean
«entity» - compontente :IComponenteCatalogo[]
Articulo - diseñoGrafico :String
- activo :boolean - fechaCreacion :Date
- codigo :String - fechaFin :Date
- fechaInicio :Date
Estructura:
- titulo :String
- nivel :int
+ agregarComponente(IComponenteCatalogo) :void - nombre :String
+ getDescripcionJerarquia() :String[]
+ getTitulo() :String + agregarComponente(IComponenteCatalogo) :void
+ obtenerHijo() :IComponenteCatalogo + getDescripcionJerarquia() :String[]
+ quitarComponente(IComponenteCatalogo) :void + getNombre() :String
+ obtenerHijo() :IComponenteCatalogo
+ quitarComponente(IComponenteCatalogo) :void
«entity» «entity»
Pelicula Musica
«entity» «entity»
Libro JuegoVideo
Composite
◎ Participantes
◉ Componente (IComponenteCatalogo)
○ Declara la interfaz de los objetos de la composición.
◉ Hoja (Articulo: Libro, Película, Música, JuegoDeVideo)
○ Implementa la operación getDescripciónJerarquía() que es uniforme a toda
la jerarquía.
◉ Compuesto (CompuestoCatalogo)
○ Implementa todas las operaciones definidas en el Componente
(IComponenteCatalogo) y las operaciones específicas para la administración
de los elementos que lo componen.
◉ Cliente (GestorCatalogo)
○ Realiza la petición al objeto que implementa la interfaz Componente
Composite: Aplicación
sd Composite
catalogo: musicaInternacional: theBeatles:
CompuestoCatalogo CompuestoCatalogo CompuestoCatalogo
: letItBe:
GestorCatalogo Musica
listarCatalogo(): String[][]
getDescripcionJerarquia(): String[]
getNombre(): String
obtenerHijo(): IComponenteCatalogo
*getDescripcionJerarquia(): String[]
Dinámica
getNombre(): String
obtenerHijo(): IComponenteCatalogo
*getDescripcionJerarquia(): String[]
getNombre(): String
obtenerHijo(): IComponenteCatalogo
*getDescripcionJerarquia(): String[]
getTitulo(): String
◉ El GestorCatalogo debe armar y mostrar toda la jerarquía del catálogo activo (X secciones, Y subsecciones y
Z artículos) cuando el usuario desea consultarlo, para lo cual le pide a la interfaz (IComponenteCatalogo)
que lo resuelva a través del método: getDescripciónJerarquía().
◉ Las clases (Artículo y CompuestoCatalogo) implementan la interfaz IComponenteCatalogo.
◉ Para el caso de Articulo (hoja) los métodos de manipulación de hijos
agregarComponente(),quitarComponente() y obtenerHijo() se implementan VACIOS.
◉ El Compuesto (CompuestoCatalogo), es quien resuelve la petición recursivamente hasta armar todo el
árbol.
◉ En el caso del ejemplo, el Catálogo está compuesto por Secciones (Música Internacional), Subsecciones
(The Beatles) y debe recorrer los artículos que lo componen (Let It Be). Esto es posible gracias al objeto
Compuesto.
◉ En la segunda parte del ejemplo, se debe recuperar el nombre de un artículo (hoja), para ello no es
necesario que intervenga el objeto Compuesto.
◉ De esa manera el GestorCatalogo obtiene el nombre de cada elemento del catálogo y su ruta de ubicación,
sin necesidad de conocer la cantidad de niveles de división del catálogo.
Patrón de Creación Patrón de Estructura Patrón de Comportamiento
Adapter/ Wrapper
(Adaptador/ Envoltorio)
130
Patrón de Creación Patrón de Estructura Patrón de Comportamiento
Propósito
Convertir la interfaz de un objeto para
que otro pueda comprenderla.
Se dice que el Adaptador “envuelve”
uno de los objetos para ocultar la
complejidad de la conversión. El
objeto “envuelto” no necesita conocer
que se realiza una conversión.
Ámbito
De clases y de objetos
Adapter 134
Aplicabilidad
• Cuando queremos usar alguna clase existente, pero su interfaz no
es compatible con el resto de su código.
• Cuando queremos crear una clase reutilizable que coopere con clases
no relacionadas o que no han sido previstas (que no tienen porqué
tener interfaces compatibles)
• Cuando queremos usar varias subclases existentes, pero no resulta
práctico adaptar su interfaz heredando de cada una de ellas.
• Como buen patrón estructural, el cometido del patrón adapter está
relacionado con la forma en la que los objetos interactúan entre
ellos.
Patrón de Creación Patrón de Estructura Patrón de Comportamiento
Aplicabilidad
Solución: Patrón Adaptador
Adapter
135
Adapter 136
Implementación
Implementación (Continuación)
3. Crear un adaptador que implemente dicha interfaz. Esto se haría para
cada una de las partes a adaptar. Cada uno de estos adaptadores
contendrá una instancia de la clase adaptada y “forzará” su uso para que se
adapte a la nueva interfaz.
4. Desacoplar el cliente de la clase concreta. En lugar de recibir una clase
concreta, a partir de ahora recibirá un objeto cualquiera que implemente la
nueva interfaz.
Estructura – Adaptador de Objeto Adapter 138
programación populares.
«interface»
Cliente
Objetivo
+ petición() : void
Adapter
Adaptable
+ petición() : void
+ peticiónConcreta() : void
Adapter 139
¿Y si miramos la arquitectura?
Patrón de Creación Patrón de Estructura Patrón de Comportamiento
arch Broker
«receptor»
MarcaTarjeta1
«remitente» «transaccion» «broker»
AutorizacionVenta Agente Intercambio Reqto_Financiero
Transacciones
Financiera
«transaccion»
Reqto_Reversa
«remitente»
«receptor»
AnulacionVenta
MarcaTarjetaN
Adapter 141
Patrón de Creación Patrón de Estructura Patrón de Comportamiento
Aplicación Venta
Digital
Estructura Análisis –
CU Autorizar Venta con
Tarjeta de Crédito
Adapter 142
Aplicación Venta Digital
Dinámica Análisis – CU Autorizar Venta con Tarjeta de Crédito
Patrón de Creación Patrón de Estructura Patrón de Comportamiento
Adapter 143
:AutorizadorTarjetaDeCreditoVisa :ServicioAutorizadorOperacionesTarjetaVisa
:GestorAutorizacionVenta
obtenerMontoVenta()
:float
validarTC(numeroTarjeta :char, fechaVto :Date, control :int, montoVenta :float, cantidadCuotas :int) :int
convertirPedidoValidacionTC(numeroTarjeta :
char, fechaVto :Date, control :int, montoVenta :
float)
convertirRespuestaAutorizacion()
Adapter 145
Ventajas – Adaptador de
Objeto
Patrón de Creación Patrón de Estructura Patrón de Comportamiento
146
Adapter
Desventajas
Patrón de Creación Patrón de Estructura Patrón de Comportamiento
147
Foto de Johannes Plenio en Unsplash.
Adapter 148
Estructura – Adaptador de Clase
Esta implementación utiliza la herencia: el adaptador hereda las interfaces de ambos
Patrón de Creación Patrón de Estructura Patrón de Comportamiento
objetos al mismo tiempo. Tenga en cuenta que este enfoque solo se puede implementar
en lenguajes de programación que admitan herencia múltiple.
Adapter 149
Desventajas - Herencia
Patrón de Creación Patrón de Estructura Patrón de Comportamiento
150
Patrón de Creación Patrón de Estructura Patrón de Comportamiento
(Recuerdo)
Memento/ Token
151
Memento 152
◎ Aplicabilidad
◉ Una parte del estado de un objeto debe ser guardado para
que pueda ser restaurado más tarde.
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Memento
◎ Consecuencias
◉ Mantiene el encapsulamiento
◉ Simplifica la clase Creador ya que no debe preocuparse de
mantener las versiones del estado interno.
◉ Podría incurrir en un considerable gasto de memoria:
encapsular y restaurar el estado no debe ser costoso.
◉ Puede ser difícil en algunos lenguajes asegurar que sólo el
Creador tenga acceso al estado del Memento.
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Memento 157
Aplicabilidad
Implementación
Implementación (Continuación)
Estructura
Memento
160
Memento 161
Aplicación + mostrarColores()
Patrón de Creación Patrón de Estructura Patrón de Comportamiento
+ mostrarPreferenciaActual() + buscarColores()
+ solicitaConfirmación() + finCU()
+ solicitarCantidadURLDe1a20() + mostrarPreferenciaActual()
Venta +
+
+
+
tomarConfirmación()
tomarOpciónPersonalizarSitioWeb()
tomarSelecciónCantidad()
tomarSelecciónColor()
+
+
+
+
nuevasPreferencias()
registrarPreferencias()
tomarCantidad()
tomarColor()
Digital Cliente
+ tomarConfirmación()
ColorPredefinido
- apellido
Estructura -
-
email
fechaNacimiento
-
-
descripción
nombre
- nombre + getNombre()
Análisis – CU -
-
-
numeroDocumento
preferencia
sexo
Personalizar -
+
+
telefono
guardarPreferencia()
mostrarPreferenciaActual()
1
LinkFavorito
- marcador
- url
sitio web + setNuevaPreferencia()
1
0..*
+ getURL()
PreferenciaCliente
- cantidadLinks
- color
- favorito
- mementoPreferencia
+ getDatos()
+ setLinksFavoritos()
+ setPreferencias()
Memento 163
Aplicación
Venta Digital
Estructura – CU
Personalizar sitio
web
Memento 165
Ventajas
Patrón de Creación Patrón de Estructura Patrón de Comportamiento
Desventajas
Patrón de Creación Patrón de Estructura Patrón de Comportamiento
(Iterador)
Iterator
171
Iterator
◎ Consecuencias
◉ Simplifica la interfaz de un contenedor al extraer
los métodos de recorrido
◉ Permite varios recorridos, concurrentes
◉ Soporta variantes en las técnicas de recorrido
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Iterador Externo Polimórfico
Herencia
Iterador
Agregado Cliente primero()
siguient e()
crearIterador()
haTerminado()
element oActual()
AgregadoConcreto IteradorConcreto
Iterador Externo Polimórfico
Realización
IIte r a d o r
IA g r e g a d o C lie n te
( fr o m L o g ic a l V ie w ) p rim e ro ()
c re a r It er a d o r( ) s ig u ie n t e ()
h a T e rm in a d o ()
e le m e n t o A c t u a l()
A g r e g a d o C o n c r e to Ite r a d o r C o n c r e to
(fro m L o g i c a l V i e w ) (fro m L o g i c a l V i e w )
class Iterator-Seccion
«interface» «interface»
IIterador
Iterator: +
IAgregado
crearIterador(elementos :Object[]) :IIterador +
+
primero() :void
siguiente() :void
+ actual() :Object
Aplicación +
+
haTerminado() :boolean
cumpleFiltro(filtros :Object[]) :boolean
«entity»
Catalogo
- seccion :SeccionCatalogo[] «iterator»
+ listarNombreSecciones() :String[] IteradorSeccion
+ listarNombreSubsecciones() :String[] - actual :int
+ getRangoVigencia() - elementos :Object[]
+ listarArticulosPorSeccion()
+ listarArticulosDestacados() + primero() :void
+ siguiente() :void
Estructura
+ buscarSeccionArtDestacados()
+ getArticulo() :Articulo + actual() :Object
+ getSeccion() :SeccionCatalogo + haTerminado() :boolean
+ new(elem :Object[])
-seccion 1..*
0..*
«entity» -subseccion
SeccionCatalogo
- nombre :String
- agrupaArtDestacados :boolean
+ crearIterador(elementos :Object[]) :IIterador
+ getNombre() :String
+ listarArticulos() :String[]
+ agrupaArtDestacados() :void
Dinámica: Iterator: Aplicación
sd Iterator-Seccion
: :Catalogo :
GestorCatalogo SeccionCatalogo
listarArticulosDestacados()
listarNombreSecciones(): crearIterador(elementos:
String[] Object[]): IIterador
getNombre(): String
siguiente()
Iterator: Aplicación
Estructura
class Iterator-Articulo
«interface»
IIterador
+ primero() :void
+ siguiente() :void
+ actual() :Object
«interface» + haTerminado() :boolean
IAgregado + cumpleFiltro(filtros :Object[]) :boolean
«iterator»
IteradorArticulo
- actual :int
«entity» - elementos :Object[]
Catalogo
+ primero() :void
- nombre + siguiente() :void
- seccion :SeccionCatalogo[] + actual() :Object
+ listarPorSeccion() :String[][] + haTerminado() :boolean
+ listarNombreSubsecciones() :String[] + cumpleFiltro(filtros :Object[]) :boolean
+ getRangoVigencia() + new(elem :Object[], filtros :Object[])
+ listarArticulosPorSeccion()
+ listarArticulosDestacados()
+ buscarSeccionArtDestacados()
+ getArticulo() :Articulo
+ getSeccion() :SeccionCatalogo
-seccion
1..*
0..* -subseccion «entity»
«entity» Articulo
SeccionCatalogo
- titulo :String
- articulo :Articulo[] -articulo - activo :boolean
- agrupaArtDestacados :boolean
0..* + tieneImagen()
+ crearIterador(elementos :Object[]) :IIterador + getTitulo() :String
+ listarArticulos() :String[] + estaActivo() :boolean
+ agrupaArtDestacados() :void
Iterator: Aplicación
Dinámica:
sd Iterator-Articulo
: :Catalogo : :
GestorCatalogo SeccionCatalogo JuegoVideo
listarPorSeccion() :String[][]
*listarArticulos() :String
siguiente()
Iterator: Aplicación
◎ Participantes
◉ Iterador [IIterador]: interfaz que permite recorrer los elementos y acceder a ellos.
◉ IteradorConcreto [IteradorArticulos, IteradorSecciones]: implementa la interfaz Iterador y
mantiene la posición actual en el recorrido del Agregado.
◉ Agregado [IAgregado]: define una interfaz para crear un objeto Iterador
◉ AgregadoConcreto [Catálogo, SeccionCatalogo]: implementa la interfaz de creación de
Iterador para devolver una instancia de un Iterador concreto (IteradorArticulos o
IteradorSecciones).
◎ Procedimiento
◉ Cuando necesitamos recorrer o mostrar los artículos (libros, películas, música o juegos) o
secciones del catálogo se invoca a los métodos listarArticulosActivos() y
listarNombreSecciones(), respectivamente.
◉ En la dinámica se mostrará el ejemplo con JuegoVideo.
◉ Este método invoca a crearIterador() para establecer el Iterador.
◉ Finalmente se definen los métodos necesarios para realizar el recorrido de los elementos:
haTerminado(), siguiente(), cumpleFiltro(), etc.
class Iterator-CompuestoCatalogo
«interface»
Iterator: Aplicación +
+
+
IIterador
primero() :void
siguiente() :void
actual() :Object
+ haTerminado() :boolean
«interface» + cumpleFiltro(filtros :Object[]) :boolean
IAgregado
+ crearIterador(elementos :Object[]) :IIterador
«iterator»
«iterador» IteradorArticulo
IteradorCompuesto
- actual :int
+ actual() :Object - elementos :Object[]
+ cumpleFiltro(filtros :Object[]) :boolean
+ haTerminado() :boolean + primero() :void
+ siguiente() :void
+ new(elementos :object[]) :void
+ primero() :void + actual() :Object
+ siguiente() :void + haTerminado() :boolean
+ cumpleFiltro(filtros :Object[]) :boolean
+ new(elem :Object[], filtros :Object[])
«control»
GestorCatalogo
CompuestoCatalogo
- criterioOrdenamiento :EstrategiaOrdenArticulos
- nombre :String
+ crearIterador(elementos :Object[]) :IIterador - diseñoGrafico :String
+ buscarCatalogoVigente() - nivel :int
+ listarEstructuraSecciones() :void - fechaInicio :Date
+ finalizarCU() :void - compontente :IComponenteCatalogo[] «entity»
+ listarCatalogo() :String[][] - agrupaArtDestacados :boolean
Articulo
+ ordenarArticulos() :void - fechaFin :Date
- fechaCreacion :Date - titulo :String
- activo :boolean
+ agregarComponente(c :IComponenteCatalogo) :void
+ getDescripcionJerarquia() :String[] + tieneImagen()
+ getNombre() :String + getTitulo() :String
Estructura +
+
+
listarArticulosActivos() :void
obtenerHijo() :IComponenteCatalogo
quitarComponente(c :IComponenteCatalogo) :void
+ estaActivo() :boolean
Iterator: Aplicación sobre el composite
Dinámica:
sd Iterator-CompuestoCatalogo
catalogo : seccionJuegoVideo :
CompuestoCatalogo CompuestoCatalogo
: :
Ge storCatalogo Jue goV ide o
listarCatalogo() :String[][]
actual() :Object
getDescripcionJerarquia() :String
getNombre() :String
new() «iterador»
:IteradorCompuesto
primero()
getDescripcionJerarquia() :String
getNombre() :String
listarArticulosActivos()
getDescripcionJerarquia() :String
getTitulo() :String
siguiente()
siguiente()
siguiente()
Iterator: Aplicación conjunta con Composite
◎ Participantes
◉ Iterador [IIterador]: interfaz que permite recorrer los elementos y acceder a ellos.
◉ IteradorConcreto [IteradorArticulos, IteradorCompuesto]: implementa la interfaz Iterador
y mantiene la posición actual en el recorrido del Agregado.
◉ Agregado [IAgregado]: define una interfaz para crear un objeto Iterador
◉ AgregadoConcreto [GestorCatálogo, CompuestoCatalogo]: implementa la interfaz de
creación de Iterador para devolver una instancia de un Iterador concreto
(IteradorArticulos o IteradorCompuesto).
◎ Procedimiento
◉ Cuando necesitamos recorrer o mostrar los artículos (libros, películas, música o juegos)
de un catálogo se invoca a los métodos listarCatalogo() y listarArticulosActivos(),
respectivamente.
◉ En la dinámica se mostrará el ejemplo con JuegoVideo.
◉ Este método invoca a crearIterador() para establecer el Iterador.
◉ Finalmente se definen los métodos necesarios para realizar el recorrido de los elementos:
haTerminado(), siguiente(), cumpleFiltro(), etc.
Façade / Fachada
◎ Propósito
◉ Proporciona una única interfaz a un conjunto de interfaces de un
subsistema. Define una interfaz de más alto nivel que facilita el uso de un
subsistema.
◎ Motivación
◉ Reducir las dependencias entre subsistemas.
◉ Un entorno de programación que ofrece una librería de clases que
proporcionan acceso a su subsistema compilador: Scanner, Parser,
ProgramNode, ByteCodeStream y ProgramNodeBuilder. Clase Compiler
actúa como fachada.
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Estructura
Fachada
Façade / Fachada
◎ Aplicabilidad
◉ Proporcionar una interfaz simple a un subsistema.
◉ Hay muchas dependencias entre clientes y las clases que
implementan una abstracción.
◉ Se desea una arquitectura de varios niveles: una fachada
define el punto de entrada para cada nivel subsistema.
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Façade / Fachada
◎ Consecuencias
◉ Facilita a los clientes el uso de un subsistema, al ocultar sus
componentes.
◉ Proporciona un acoplamiento débil entre un subsistema y los
clientes: cambios en los componentes no afectan a los clientes.
◉ No se impide a los clientes el uso de las clases del subsistema si
lo necesitan. Se puede elegir entre facilidad y funcionalidad
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Façade: cmp Facade
GestionVenta
«fachada»
FachadaEnvio
Estructura +
+
+
listarDestinosActivos() : String[]
distribuyeALocalidad(loc :Localidad) : boolean
listarEmpresasTransporte() : String[]
+ existeDestino(dest :Destino) : boolean
+ listarFormasEnvio() : String[]
+ new()
«entity» «entity»
FormaEnvio Localidad
- nombre: String
-localidad 1
+ getNombre() : String
«entity»
Destino
«entity» - nombre: String
EmpresaTransporte - localidad: Localidad
- activo: boolean
- razonSocial: String
+ estáActivo() : boolean
+ getRazonSocial() : String + getNombre() : String
Façade / Fachada
◎ Participantes
◎ Procedimiento
*getNombre() :String
listarFormasEnvio() :String[]
*getNombre() :String
◎ Ventajas:
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Singleton
Estructura
S in g le to n new:
$ i n s ta n c i a U n i c a
s o b re M i
d e v u e lv e
u n a ú n ic a
n e w () in s ta n c ia
o b te n e r D a to s S i n g l e to n ( )
o tr o s M e to d o s ( )
Singleton
◎ Aplicabilidad
«entity»
Pedido El método getInstancia() es
- numero :int ESTÁTICO. Se ocupa de crear la
+ new(nro :int) instancia única -atributo instancia- si
aún no fue creada.
Singleton: Aplicación
◎ Participantes
◉ Singleton [NumeroPedido]: proporciona un constructor privado, mantiene una
referencia estática a la única instancia de la clase, y proporciona un método estático de
acceso -getInstancia()- para devolver una referencia a la misma, permitiendo que los
clientes accedan a la única instancia de la clase.
◎ Procedimiento
◉ Cuando necesitemos crear un nuevo pedido y por lo tanto asignarle su
correspondiente número, el gestor de pedido le pediría al Singleton (NumeroPedido),
el número de pedido que debe asignar al nuevo pedido.
◉ El Singleton tiene un atributo estático para mantener la referencia a la instancia única y
uno o más atributos que guardan el estado relevante del objeto -el último número
asignado. Crea la instancia única y le devuelve al Gestor el número.
◉ El gestor de pedido invoca el método new() del pedido pasándole como parámetro
entre otras cosas el número de pedido que corresponde y luego le pide al Singleton
que actualice el valor del atributo estático.
Singleton: sd Singleton
«singleton»
Aplicación :GestorPedido
:NumeroPedido
◎ Dinámica crearPedido()
calcularNumeroPedido() :int
Se crea la instancia del
getInstancia() :NumeroPedido Singleton -si aún no existe.
new()
getNumero() :int
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Iterator (Iterador)
◎ Motivación
◉ Una clase Iterator define la interfaz para acceder a una
estructura de datos (p.e. una lista).
◉ Iteradores externos vs. Iteradores internos.
◉ Iteradores externos: recorrido controlado por el cliente
◉ Iteradores internos: recorrido controlado por el iterador
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Abstract Factory (Factoría Abstracta)
◎ Propósito
◉ Proporcionar una interfaz para crear familias de
objetos relacionados o dependientes sin especificar la
clase concreta
◎ Motivación
◉ Un toolkit interfaz de usuario que soporta diferentes
formatos: Windows, Motif, X-Windows,..
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Abstract Factory
Estructura Realización
FabricaAbstracta Cliente
crearProductoA()
crearProductoB()
ProductoAbstractoA
FabricaConcreta1 FabricaConcreta2
ProductoA2
crearProductoA() crearProductoA() ProductoA1
crearProductoB() crearProductoB()
ProductoAbstractoB
ProductoB2 ProductoB1
Abstract Factory
Estructura
Cliente
FabricaAbstracta ProductoAbstractoA
crearProductoA()
crearProductoB()
FabricaConcreta1 FabricaConcreta2
ProductoA2 ProductoA1
crearProductoA() crearProductoA()
crearProductoB() crearProductoB()
ProductoAbstractoB
ProductoB2 ProductoB1
Herencia
Abstract Factory
◎ Aplicabilidad
◉ Un sistema debería ser independiente de cómo sus productos son
creados, compuestos y representados
◉ Un sistema debería ser configurado para una familia de productos.
◉ Una familia de objetos productos relacionados es diseñado para ser
utilizado juntos y se necesita forzar la restricción.
◉ Se quiere proporcionar una librería de clases de productos y se quiere
revelar sólo la interfaz, no la implementación.
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Abstract Factory
◎ Consecuencias
◉ Aísla a los clientes de las clases concretas de
implementación.
◉ Facilita el intercambio de familias de productos.
◉ Favorece la consistencia entre productos
◉ Es difícil soportar nuevas clases de productos.
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Abstract Factory
◎ Implementación
◉ Factorías como singleton.
◉ Se necesita una subclase de AbstractFactory por cada clase de
producto que redefine un método factoría.
◉ Posibilidad de usar el patrón Prototype.
◉ Definir factorías extensibles: AbstractFactory sólo necesita un
método de creación. DEPENDE DEL LENGUAJE
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Abstract Factory
◎ Procedimiento
◉ Analizar la situación determinando elementos que siendo del mismo tipo varían
en su comportamiento (Productos).
◉ Identificar el patrón que da origen a las variaciones en los productos (fábricas).
◉ Implementar las características que varían de los productos es decir:
implementar los productos concretos.
◉ Implementar las fábricas concretas que crean los productos concretos.
◉ Establecer en el cliente la relación de conocimiento con la fábrica abstracta y el
producto abstracto.
◉ Entendemos que el cliente recibirá por parámetros la identificación de la fábrica
concreta. Y a partir de esta última se determinarán los productos concretos que
corresponda.
Abstract Factory: Aplicación
Estructura
class AbstractFactory
«control»
GestorCliente
«entity» - fabrica: IFabricaPais
Cliente
+ aplicarFormatoPais(): void
- email: String + formatearFechaNacimiento(): String
- fechaNacimiento: Date + formatearTelefono(): String
- telefono: String
+ getEMail(): void
+ getFechaNacimiento(): Date
«interface»
+ getPais(): Pais
+ listarTarjetasNoVencidas(): void IInfoPersonal
+ formatearCodPostal(cod: String): String
+ formatearNroTelefono(t: String): String
«entity»
Pais «producto»
InfoPersonalChi «producto»
- fabrica: IFabricaPais InfoPersonalArg
- nombe: String - formatoCodPostal: String
- formatoTelefono: String - formatoCodPostal: String
+ getFabrica(): IFabricaPais - formatoTelefono: String
+ getNombre(): String «fabrica»
FabricaChile
«interface»
ICalendario
1
+ formatearFecha(d: Date): String
«interface» «producto» + formatearFechaLarga(d: Date): String
IFabricaPais CalendarioChile + formatearHora(d: Date): String
+ formatearCodPostal(cod: String): String - formatoFecha: String
+ formatearFecha(calendario: ICalendario, d: Date): String - formatoFechaLarga: String
+ formatearFechaLarga(d: Date): String - formatoHora: String
+ formatearHora(d: Date): String - separadorFecha: char
+ formatearNroTelefono(telefono: IInfoPersonal, t: String): String - separadorHora: char
«producto»
CalendarioArg
- formatoFecha: String
- formatoFechaLarga: String
- formatoHora: String
«fabrica»
- separadorFecha: char
FabricaArgentina
- separadorHora: char
+ crearCalendarioArg(): ICalendario + new(): CalendarioArg
+ crearInfoPersonalArg(): IInfoPersonal
+ formatearCodPostal(cod: String): String
+ formatearFecha(calendario: ICalendario, d: Date): String
+ formatearFechaLarga(d: Date): String
+ formatearHora(d: Date): String
+ formatearNroTelefono(telefono: IInfoPersonal, t: String): String
Abstract Factory
◎ Participantes
getPais(): Pais
getFabrica(): IFabricaPais
crearCalendarioArg(): ICalendario
new(): CalendarioArg «producto»
:CalendarioArg
formatearFechaNacimiento(): String
getFechaNacimiento(): Date
formatearTelefono(): String
getTelefono(): String
conocerFechaActual( )
determinarFechaActual( )
determinarPais( )
getPais( )
formatearFechaLarga(d : Date)
mostrarFechaActual(String)
Abstract Factory
◎ Procedimiento
Des pachadoParcial 1
Pedido
(f rom Analy sis Model)
Es tado 1
Carrito 1..*
1 Des tino
Entregado 1 (f rom Analy sis Model)
1
CarritoCom pleto MedioTrans porte
Form aEnvío
(f rom Analy sis Model)
1..* (f rom Analy sis Model)
Des pachado 1..* 1
Cerrado Provincia
Localidad
DetallePedido 0..* (f rom Analy sis Model)
(f rom Analy sis Model)
(f rom Analy sis Model)
Cliente 1..* 0..*
1
(f rom Analy sis Model) Articulo
(from Analysis Model)
Em presaTrans porte
TipoArticulo 1 1..* (f rom Analy sis Model)
(f rom Analy sis Model) Pais
(f rom Analy sis Model)
Ges torDeCons ultas 1
(f rom Analy sis Model)
Catálogo
(f rom Analy sis Model)
DirectorCons truccionCatalogo
Lis ta
1
1..*
Resultante 1
PantallaCatalogoRes um enWeb
1
Im pres orCatalogo
1
PantallaCatalogoWeb
Mapeo de Clases a Bases de Datos
Relacionales
212
Problema de Impedancia
◎ Los tipos a ser usados en las
tablas son mayormente los
tipos primitivos
Memoria Volatil
◎ La información se almacena en
los objetos. Por lo tanto
necesitamos transformar
nuestra estructura de Memoria
información de objeto a una Persistente
estructura orientada a tablas
◎ Crea un fuerte acoplamiento
entre la aplicación y el DBMS
Objetos en Tablas
◎ (1) Asignar una tabla para la clase.
◎ (2) Cada atributo (primitivo) se transformará en una columna en la tabla.
Si el atributo es complejo (es decir, debe componerse de tipos de DBMS),
o agregamos una tabla adicional para el atributo, o distribuimos el
atributo en varias columnas de la tabla de la clase.
◎ (3) La columna de la clave primaria será el identificador único de la
instancia, llamado identificador.
◎ (4) Cada instancia de la clase ahora será representada por una fila en
esta tabla.
◎ (5) Cada asociación de conocimiento con una cardinalidad mayor que 1
(por ejemplo, [0..N]) se transformará en una nueva tabla. Esta nueva
tabla conectará las tablas que representan los objetos que van a ser
asociados.
Objetos en Tablas
(b)
Solución: Super Objeto Persistente
ObjectToStore
Object ObjectState
PersistentObjectAdministrador PersistentState
RDBPort
hereda
Item ItemState
PersistentItemAdministrador PersistentItemState
Objetos en Tablas: Herencia
ECU
Valor de Depósito[1]
Nombre [1]
String
Total Diario [1]
Entero
hereda Item de
Depósito Medidas
hereda Ancho del Cuello [1]
String
Alto [1]
Ancho [1] Medidas
Medidas
Ancho Inferior [1] String
Alto [1] String
Medidas Botella Medidas
Lata
String
Eliminar la Herencia
Nombre Lata Valor de Depósito Total Diario Alto Ancho
Nombre Botella Valor de Depósito Total Diario Alto Ancho Inferior Ancho del Cuello
Lata Botella
Nombre Lata Alto Ancho Nombre Botella Alto Ancho InferiorAncho del Cuello
V e n ta n a
C o o rd in a d o rD e A p lic a c io n e s
D o m in io
E s q u e m a P e r s i s te n c i a R e l a c i o n a l O b j e to s
Base de Datos
Relacional
Ideas a desarrollar…
◎ Correspondencia (Mapping): entre clases y tablas; entre atributos y campos. Es decir
correspondencia de “esquemas”.
◎ Identidad de Objeto: identificador único que vincula objetos con registros.
◎ Materialización: transformar un registro en objeto
◎ Desmaterialización: transformar un objeto en registro.
◎ Conversor de Base de Datos: es el responsable de la materialización y desmaterialización de los
objetos.
◎ Caché: Almacén de objetos materializados en esta memoria por cuestiones de rendimiento.
◎ Estado de Transacción de los objetos: El estado de los objetos para saber si se modificaron en
función de su estado almacenado.
◎ Operaciones de Transacción: confirmar y deshacer
◎ Materialización Perezosa: no todos los objetos se materializan a la vez, se hace bajo demanda, es
decir, cuando se lo necesita.
◎ Proxies Virtuales: Referencia inteligente utilizada para la materialización perezosa.
Patrón: Identificador de Objetos
// e je m p lo d e u s o d e la fa c h a d a
O ID o id = n e w O ID ( "X Y Z 1 2 3 ) ;
E s p e c ific a c io n D e lP r o d u c to e p = ( E s p e c ific a c io n D e lP r o d u c to ) F a c h a d a D e P e r s is te n c ia .g e tIn s ta n c ia ( ) . g e t( o id ,
E s p e c ific a c io n D e lP r o d u c to .c la s s ) ;
Responsabilidad de Materializar y Desmaterializar
Objetos
◎ La fachada no hace el trabajo, solo lo delega en objetos del subsistema.
◎ El patrón Experto, sugiere que la propia clase de dominio
(EspecificacionDelProducto) es candidata porque tiene los datos que se van a
almacenar. Esto se denomina correspondencia directa.
◎ Se puede utilizar la correspondencia directa si el código relacionado a la BD se
genera y se inyecta automáticamente mediante un compilador de post-
procesamiento, y el desarrollador nunca tiene que ver o mantener ese código
que añade confusión a la clase provocando:
◉ Fuerte acoplamiento de la clase persistente con su almacenamiento. (Violación del
Patrón Bajo Acoplamiento).
◉ Responsabilidades complejas y no relacionadas (Violación del Patrón Alta Cohesión).
Patrón Conversor (Mapper) de Base de Datos o
Intermediario (Broker) de Base de Datos
C o n v e rs o r B D R E s p e c if ic a cio n D e lP r o d u c to C o n v e r s o r B D R F a b r ic a n te
C O n v e r s o r F ic h e r o E s p e c ific a c io n D e lP r o d u c to
g e t:O b je c t( O ID , C la s s ) g e t:O b je c t( O ID , C la s s )
g e t:O b je c t( O ID , C la s s )
g e t:O b je c t( O ID , C la s s ) p u t( O ID , O b je c t)
p u t( O ID , O b je c t)
p u t( O ID , O b je c t)
N o te s e q u e ya n o s e n e c e s i ta C a d a c o n ve rs o r o b ti e n e y a l m a c e n a l o s o b je to s a s u m a n e r a
C la s s c o m o p a rá m e tro e n e s ta ú n i c a , d e p e n d i e n d o d e l ti p o d e a lm a c e n a m ie n to d e d a to s y d e l
ve rs i ó n d e g e t, ya q u e la c la s e fo rm a to
" e s tá c o n e c ta d a " a u n ti p o
p e rs i s te n te c o n c re to
Bridge / Handle
◎ Propósito
◉ Desacoplar una abstracción de su implementación, de modo que los dos
puedan cambiar independientemente.
◎ Motivación
◉ Clase que modela la abstracción con subclases que la implementan de
distintos modos.
◉ Herencia hace difícil reutilizar abstracciones e implementaciones de
forma independiente
○ Si refinamos la abstracción en una nueva subclase, está tendrá
tantas subclases como tenía su superclase.
○ El código cliente es dependiente de la plataforma.
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Bridge / Handle
Estructura
Herencia
Cliente
operacion() operacionImp()
imp->operacionImp();
operacionImp() operacionImp()
Bridge / Handle
Estructura
Realización
C lie n te A b s tr a c c io n im p Im p le m e n ta d o r
o p e ra c io n () o p e ra c io n Im p ()
im p -> o p e ra c io n Im p ();
Im p C o n c r e to A Im p C o n cr e t o B
A b s tr a c c io n R e fin a d a o p e ra c io n Im p ()
o p e ra c io n Im p ()
Bridge
◎ Aplicabilidad
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Bridge
◎ Implementación
◉ Aunque exista una única implementación puede usarse el
patrón para evitar que un cliente se vea afectado si cambia.
◉ ¿Cómo, cuándo y dónde se decide que implementación usar?
○ Constructor de la clase Abstraccion
○ Elegir una implementación por defecto
○ Delegar a otro objeto, p.e. un objeto factoría
◉ Se puede usar herencia múltiple para heredar de la abstracción
y de una implementación concreta, pero se liga una interface a
una implementación de forma permanente.
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Bridge Estructura
class Bridge
«control»
GestorCliente «entity»
Pedido
+ crearPedido() : void
+ guardarPedido() : void + armarEstadoPedido(comando :OrdenBD) : void
«interface»
«abstraccion» ImpIntermediarioBD
IntermediarioBD
+ dematerializeWith(obj :Object) : void
+ valorObjeto(objeto :Object) : void + existeOID(id :String) : boolean
+ materializeWith() : Object
crearPedido()
new(nro :int)
Dinámica :Pedido
guardarPedido()
valorObjeto(objeto :Object)
existeOID(id :String) :boolean
dematerializeWith(obj :Object)
Template Method
◎ Propósito
◉ Define el esqueleto (esquema, patrón) de un algoritmo en
una operación, difiriendo algunos pasos a las subclases.
Permite a las subclases redefinir ciertos pasos de un
algoritmo sin cambiar la estructura del algoritmo.
◎ Motivación
◉ Fundamental para escribir código en un framework.
◉ Clase Aplicación que maneja objetos de la clase Documento:
método OpenDocument
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Método Plantilla para
un Framework de GUI
// éste es el método plantilla, su algoritmo
ComponenteG Clase del
es la parte que no varía UI FRAMEWORK
repintar();
} MiBotonExcel
ente Nuestra
Método de enganche Clase
-parte variable
-redefinido en las subclases
repintar()
- podría ser abstracto o teneruna
implementación por defecto.
C o n v e r s o r P e r s is te n c ia A b s tr a c to
g e t( O ID ) : O b je c t {le a f} E n g a n ch e
g e tO b je t o D e A l m a ce n a m ie n to ( O ID ) : O b je to { a s t ra ct}
{
Redefinición del Método de Enganche
//m é to d o p l a n ti l l a
p u b l i c fi n a l O b j e c t g e t ( O ID o i d )
{
o b j := o b j e to E n C a c h e .g e t( o i d ) ; C o n v e r s o r P e r s is te n c ia A b s tr a c to
if (o b j = = n u ll)
{
// m é to d o e n g a n c h e g e t( O ID ) : O b je c t { le a f }
obj =
g e tO b j e to D e Al m a c e n a m i e n to ( o i d ) ;
g e tO b je to D e A lm a c e n a m ie n to ( O ID ) : O b je to { a s tra c t} IC o n v e rs o r
o b j e to E n C a c h e .p u t ( o i d , o b j ) ;
}
r e tu r n o b j ;
}
}
C o n v e rs o rB D R E s p e c if ic a c io n D e lP ro d u c to
{
// r e d e fi n i c i ó n d e l m é to d o d e e n g a n c h e
p r o te c te d O b j e c t g e tO b j e to D e Al m a c e n a m i e n to ( O ID g e tO b je to D e A lm a c e n a m ie n to ( O ID ) : O b je c t
o id )
{
S tr i n g c l a ve = o i d .s tr i n g ( ) ;
r e g D B = r e s u l ta d o d e l a e j e c u c i ó n S Q L :
"S e l e c t * fr o m E S P E C _ P R O D w h e r e c l a ve = " + c l a ve
E s p e c i fi c a c i o n D e l P r o d u c to e p = n e w
E s p e c i fi c a c i o n D e l P r o d u c to ( ) ;
e p .s e tO ID ( o i d ) ;
e p .s e tP r e c i o ( r e g D B .g e tC o l u m n ( "P R E C IO ") ) ;
e p .s e tA r ti c u l o ID ( r e g D B .g e tC o l u m n ( "A R T IC U L O _ ID ") ) ;
e p .s e tD e s c r i p c i o n ( r e g D B .g e tC o l u m n ( "D E S C ") ) ;
r e tu r n e p ;
}
}
Ajustando el código con el Método Plantilla
{ C o n v e r s o r P e r s is te n c ia A b s tr a c to
p r o te c te d fi n a l O b j e c t
g e tO b j e to D e l A l m a c e n a m i e n to (O ID o i d )
{ g e t( O ID ) : O b je c t {l e a f}
r e g D B = g e tR e g i s tro D B (o i d );
//m é to d o d e e n g a n c h e
g e tO b j e to D e Al m a c e n a m i e n to ( O ID ) : O b je to { a s t r a c t} IC o n ve rs o r
re tu rn g e tO b j e c to D e l R e g i s tro (o i d , r e g D B );
}
}
C o n v e r s o r B D R A b s tr a c to
n o m b r e T a b la : S tr in g
{
p r i va te R e g i s tr o D B g e tR e g i s tr o D B ( O ID o i d )
{ g e tO b je to D e A lm a c e n a m ie n t o ( O ID ) : O b je t o { le a f}
S tri n g c l a ve = o i d .to S tr i n g ( ) ;
re g D B = r e s u l ta d o d e l a e j e c u c i ó n S Q L :
< < c o n s tr u c to r > > C o n v e r s o r B D R A b s tr a c to ( n o m b r e T a b la )
" S e l e c t * fr o m + n o m b re T a b l a + "w h e r e c l a ve = " + c l a ve g e tO b je to D e lR e g i s tro (O ID , R e g ist r o D B ) : O b je c t { a b s r a c t}
re tu rn r e g D B ; g e tR e g is tr o D B ( O ID ) : R e g is tr o D B
}
}
{
// M é to d o d e e n g a n c h e re d e fi n i d o
p ro te c te d O b j e c t g e tO b j e to D e l R e g i s tr o (O ID o i d , R e g i s tr o D B re g D B )
{
E s p e c i fi c a c i o n D e l P ro d u c to e p = n e w E s p e c i fi c a c i o n D e l P ro d u c to () ; C o n v e rs o r B D R E s p e c ific a c io n D e lP r o d u c to
e p .s e tO ID ( o i d ) ;
e p .s e tP r e c i o ( r e g D B .g e tC o l u m n (" P R E C IO ") );
e p .s e tA rti c u l o ID (r e g D B .g e tC o l u m n ( "A R T IC U L O _ ID ") ); g e tO b je to D e lR e g is tr o ( O ID , R e g is tr o D B ) : O b je c t
e p .s e tD e s c r i p c i o n ( re g D B .g e tC o l u m n (" D E S C ") ); < < c o n s tr u c to r > > C o n v e r s o r B D R E s p e c ific a c io n D e lP r o d u c to ( n o m T a b la )
r e tu r n e p ;
}
}
Framework de Persistencia
P e r s i s te n c i a
C o n v e r s o r B D R A b s tr a c to
n o m b r e T a b l a : S tr i n g C o n v e r s o r P e r s i s te n c i a A b s tr a c to
g e tO b j e to D e A l m a c e n a m i e n to ( )
g e t( )
< < c o n s tr u c to r > > C o n ve r s o r B D R A b s tr a c to ( )
g e tO b j e to D e A l m a c e n a m i e n to ( )
g e tO b j e to D e l R e g i s tr o ( )
g e tR e g i s tr o D B ( )
P e r s i s te n c i a N u e v a E r a
ConversorBDREspecificacionDelProducto
(from PersistenciaNuevaEra) COnversorFicheroCOnXMLEspecificacionDelProducto
<<constructor>> ConversorBDREspecificacionDelProducto(nomTabla) getObjetoDeAlmacenamiento: Objeto()
getObjetoDelRegistro(OID, RegistroDB) : Object
ConversorBDRVenta ConversorPruebaDeDatoEnMemoriaEspecificacionDelProducto
getObjetoDelRegistro(OID, RegistroDB) : Object getObjetoDeAlmacenamiento: Objeto(OID)
Patrón: Gestión de Caché
◎ Es conveniente mantener los objetos materializados en un caché local para
mejorar el rendimiento de y dar soporte a las operaciones de gestión de las
transacciones.
◎ El patrón propone que el ConversorBDR sea el responsable de mantener
esta caché, es decir cada conversor de objetos persistente sea responsable
de mantener su propia caché.
◎ Al materializar los objetos, quedan en el caché con su OID como clave.
◎ El conversor primero busca en la caché para evitar materializaciones
innecesarias.
Sentencias SQL
◎ Sentencias SQL en distintas clases conversores no es terrible, pero se
puede mejorar…
◎ En lugar de eso:
◉ Existe una única clase OperacionesBRD, donde se reúnen las
operaciones SQL (SELECT, INSERT…)
◉ Las clases conversores colaboran con ella para obtener un registro de
BD o un conjunto de registros (por ejemplo ResultSet)
◎ Con esta solución se obtienen los siguientes beneficios:
◉ Facilita mantenimiento y rendimiento.
◉ Encapsulamiento de métodos y detalles de acceso.
Estados Transaccionales
◎ Los objetos persistentes pueden insertarse, eliminarse o
modificarse.
◎ Operar sobre un objeto persistente no provoca una
actualización inmediata sobre la BD, más bien se debe ejecutar
una operación commit explícita.
◎ Además considerar que la respuesta a una operación depende
del estado de las transacción del objeto.
Máquina de Estado: Objeto Persistente
ne w[ d e sd e la B D ]
sa ve
ne w[ no d e sd e la B D ]
ro llb a ck / re ca rg a r
E lim ina d o
co m m it /e lim ina r
State
C o n te xto + e s ta d o E s ta d o
s o lic it u d () o p e ra c io n ()
e s ta d o .o p e r a c io n ( )
E s ta d o C o n c r e to 1 E s ta d o C o n c r e to 2
o p e ra c io n () o p e ra c io n ()
Objetos Persistentes
◎ La situación genérica de diseño responde a esta
estructura:
D o m in io P e rs is te n c ia
O b je to P e r s is te n te
o id : O ID
m a r c a D e T ie m p o : F e c h a H o ra
E s p e c ific a c io n D e lP ro d u c to
c o m m it( )
ro llb a c k ()
e lim in a r ()
g u a rd a r ()
Objeto Persistente y el Patrón Estado
◎ Esta es la situación que se resolverá con el patrón Estado, los métodos commit y
rollback requieren una estructura similar de lógica de casos, basada en el estado
de la transacción, ambos métodos ejecutan diferentes acciones pero tienen
estructuras lógicas similares.
Public void commit() Public void rollback()
{ {
Switch (estado) Switch (estado)
{ {
Case VIEJO_SUCIO Case VIEJO_SUCIO
//… //…
break; break;
Case VIEJO_SUCIO Case VIEJO_SUCIO
//… //…
break; break;
… …
} }
Aplicación del Patrón Estado
rollback ={estado.rollback (this)}
commit={estado.commit (this)}
eliminar ={estado.eliminar (this)}
guardar ={estado.guardar (this)} ObjetoPersistente
oid : OID EstadoObjetoP
marcaDeTiempo : FechaHora {
commit(obj : ObjetoPersistente) // por defecto
commit() // cuerpos vacíos para
1 rollback(obj : ObjetoPersistente) // cada método
rollback() eliminar(obj : ObjetoPersistente) }
eliminar() guardar(obj : ObjetoPersistente)
guardar()
{ // commit
FachadaDePersistencia.getInstancia().actualizar (obj)
obj.setEstado(EstadoViejoLimpio.getInstancia() )}
{ // rollback
FachadaDePersistencia.getInstancia().recargar (obj) { // commit
obj.setEstado(EstadoViejoLimpio.getInstancia() )} FachadaDePersistencia.getInstancia().insertar (obj)
obj.setEstado(EstadoViejoLimpio.getInstancia() )}
{ // eliminar
obj.setEstado(EstadoViejoAEliminar.getInstancia() )} { // commit
FachadaDePersistencia.getInstancia().eliminar (obj)
obj.setEstado(EstadoViejoAEliminar.getInstancia() )}
{ // guardar
obj.setEstado(EstadoViejoSucio.getInstancia() )}
Diseño de una transacción
◎ Transacción: unidad de trabajo (conjunto de tareas) cuya
terminación es atómica.
◎ En los servicios de persistencia incluyen: inserción, actualización,
eliminación de objetos.
◎ Una transacción puede incluir por ejemplo: 2 inserciones, una
actualización y tres eliminaciones.
◎ Considerar que el orden en que la aplicación añade las tareas podría
no reflejar el mejor orden de ejecución. Las tareas necesitan que se
ordenen justo antes de la ejecución.
◎ Para ello se utiliza el Patrón COMMAND.
Command
◎ Propósito
◉ Encapsula un mensaje como un objeto, permitiendo
parametrizar los clientes con diferentes solicitudes, añadir a
una cola las solicitudes y soportar funcionalidad
deshacer/rehacer (undo/redo)
◎ Motivación
◉ Algunas veces es necesario enviar mensaje a un objeto sin
conocer el selector del mensaje o el objeto receptor.
◉ Por ejemplo widgets (botones, menús,..) realizan una acción
como respuesta a la interacción del usuario, pero no se
puede explicitar en su implementación.
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Command
Estructura
Herencia
Orden
Cliente Invocador
ejecutar()
Receptor
+receptor OrdenConcreta
acción()
estado
ejecutar:
receptor.acción()
ejecutar()
Command
Estructura
Realización
IO r d e n
In v o c a d o r
C lie n te e je c u ta r ( )
e j e c u ta r :
R e c e p to r r e c e p to r.a c c ió n ( )
a c c ió n () + r e c e p to r
O r d e n C o n c re ta
e s ta d o
e je c u ta r ( )
Command
Colaboración
Crea comando indicando receptor
r : Receptor : Client e co : Command : Invocador
1. Command (r)
2. regist rarCommand(co)
3. ejecutar()
} inicialización
3.1. accion()
} uso
Command
◎ Aplicabilidad
◉ Parametrizar objetos por la acción a realizar (en lenguajes
procedurales con funciones Callback: función que es registrada en el
sistema para ser llamada más tarde
◉ Especificar, encolar y ejecutar mensajes en diferentes instantes: un
objeto Command tiene un tiempo de vida independiente de la
solicitud original.
◉ Soportar facilidad undo/redo: la operación execute puede guardar
información para revertir su efecto.
◉ Recuperación de fallos.
◉ Modelar transacciones vía conjunto de comandos
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Command
◎ Consecuencias
◉ Desacopla el objeto que invoca la operación del objeto que sabe
cómo realizarla.
◉ Cada subclase CommandConcreto especifica un par
receptor/accion, almacenando el receptor como un atributo e
implementando el método ejecutar.
◉ Objetos command pueden ser manipulados como cualquier otro
objeto.
◉ Se pueden crear command compuestos (aplicando el patrón
Composite).
◉ Es fácil añadir nuevos commands.
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Command : Aplicación
Estructura
P e d id o
( fr o m A n a lys is M o d e l)
a rm a rE s ta d o P e d id o ( c o m a n d o : O r d e n B D )
O rd e n B D
(fro m D e s i g n M o d e l ) G e s to r P e d id o
( fr o m A n a lys is M o d e l)
e je c u ta r ( )
c r e a r In t e r m e d ia r io ( ) : In te r m e d ia rio B D
c r e a r P e d id o ( )
c r e a r R e g is tr a r P e d id o ( ) : R e g is tr a r P e d id o
M o d i fic ar P e d id o
In te rm e d i a r i o B D
(fro m D e s i g n M o d e l )
R e g is tr a r P e d id o
v a lo r O b je to () : O b je c t
n e w (in t e r m e d ia r io B D R e la c io n a l : In t e r m e d ia r io B D )
r e g is t ra r F o r m a E n v io ( fe : F o rm a E n v io )
r e g is t ra r M e d io T r a n s p o r te ( m t : M e d io T ra n s p o r te ) In te r m e d ia r io B D R e la c io n a l In t e r m e d ia r io B D O O b je to s
r e g is t ra r A rt íc u lo s ( a rtic u lo s : A r tic u lo s [] ) (fro m D e s i g n M o d e l) (fro m D e s i g n M o d e l)
r e g is t ra r C lie n te D e P e d id o ( c li : C lie n t e )
e je c u ta r( p : P e d id o ) g u a r d a r( s c rip t : S tr in g [])
n e w ()
In te rm e d ia r io B D P ro d In te r m e d ia rio B D P e d id o
(fro m D e s i g n M o d e l) (fro m D e s i g n M o d e l)
Command : Aplicación
◎ Participantes
◉ Orden [OrdenDB]: Declara una interfaz para ejecutar una acción.
◉ OrdenConcreta [RegistrarPedido, ModificarPedido]: Define un enlace
para que el objeto Receptor realice una acción.
◉ Cliente [GestorPedido]: Crea un objeto OrdenConcreta y le indica el
Receptor correspondiente.
◉ Invocador [Pedido]: Solicita a la orden que ejecute una operación.
◉ Receptor [IntermediarioBD, IntermediarioBDRelacional,
IntermediarioBDOObjetos]: Sabe cuando realizar las operaciones
asociadas a una petición.
Command : Aplicación
◎ Procedimiento
◉ El GestorPedido crea la instancia del IntermediarioBD que
utilizará para guardar el Pedido recién creado.
◉ A continuación, crea la OrdenBD –comando- apropiada para
registrar el pedido.
◉ Luego le solicita al mismo Pedido que se guarde.
◉ El Pedido ejecuta la orden para que se registre el mismo.
◉ La Orden RegistrarPedido llama a sus propios métodos para
realizar la operación solicitada, y finalmente le pide
colaboración a un IntermediarioBD para guardarse en la base
de datos.
Command : : GestorPedido
crearPedido( )
new( )
: Pedido :
RegistrarPedido
:
IntermediarioBDRelacional
Aplicación crearIntermediario( )
new( )
crearRegistrarPedido( )
new(intermediarioBDRelacional : IntermediarioBD)
registrarClienteDePedido(cli : Cliente)
registrarFormaEnvio(fe : FormaEnvio)
registrarMedioTransporte(mt : MedioTransporte)
* registrarArtículos(articulos : Articulos[])
guardar(script : String[])
Command : Aplicación
◎ Ventajas
◉ Reduce el acoplamiento: La clase GestorPedido no necesita conocer quien
resuelve su petición para registrar un pedido en la base de datos.
◉ Las órdenes son métodos complejos tratados como clases, por lo que
tienen las ventajas de éstas: Reusabilidad, Cohesión, ser referenciada desde
otra clase.
◉ Para órdenes demasiado complejas es posible diseñar una agregación con
una OrdenMacro que contiene objetos Orden. (Patrón Composite)
◉ Existe mayor flexibilidad para agregar órdenes, ya que simplemente se
agregan clases, no es necesario modificar internamente a otras clases.
Command : Aplicación
class Command
«entity» «control»
Pedido GestorPedido
«abstraccion»
«interface»
IntermediarioBD
OrdenBD
+ ejecutar(obj :Object) : void «comando» + valorObjeto(objeto :Object) : void
RegistrarPedido
+ ejecutar(obj :Object) : void
+ new(interm :IntermediarioBD) : void
+ registrarClienteDePedido(cli :Cliente) : void «abstraccion»
+ registrarDetallePedido(detalle :DetallePedido[]) : void
IntermediarioBDPedido
+ registrarFormaEnvio(fe :FormaEnvio) : void
+ registrarMedioTransporte(mt :MedioTransporte) : void + new() : void
«interface»
«implementador» ImpIntermediarioBD
ImpIntermediarioBDR
+ dematerializeWith(obj :Object) : void
- guardar(script :String[]) : boolean + existeOID(id :String) : boolean
+ new() : void + materializeWith() : Object
Command : Aplicación
◎ Participantes
◉ Orden [OrdenDB]: Declara una interfaz para ejecutar una acción.
◉ OrdenConcreta [RegistrarPedido, ModificarPedido]: Define un enlace
para que el objeto Receptor realice una acción.
◉ Cliente [GestorPedido]: Crea un objeto OrdenConcreta y le indica el
Receptor correspondiente.
◉ Invocador [Pedido]: Solicita a la orden que ejecute una operación.
◉ Receptor [IntermediarioBD, IntermediarioBDPedido]: Delega las
operaciones asociadas a una petición a los implementadores.
◉ Ejecutor: [ImpIntermediarioBD, ImpIntermediarioBDR]: Resuelve la
petición de guardar el pedido en la base de datos correspondiente, en
este caso BDR.
Command : Aplicación
◎ Procedimiento
◉ El GestorPedido crea la instancia del ImpIntermediarioBDR que
utilizará para guardar el Pedido recién creado.
◉ A continuación, crea la OrdenBD –comando- apropiada para
registrar el pedido.
◉ Luego le solicita al mismo Pedido que se guarde.
◉ El Pedido ejecuta la orden para que se registre el mismo.
◉ La Orden RegistrarPedido llama a sus propios métodos para
realizar la operación solicitada, y finalmente le pide
colaboración a un IntermediarioBDPedido para guardarse en la
base de datos.
Command : Aplicación
sd Command
Dinámica
:GestorPedido
crearPedido()
new(nro :int)
:Pedido
crearIntermediario() :IntermediarioBD
new() «implementador»
:ImpIntermediarioBDR
crearRegistrarPedido()
new(interm :IntermediarioBD) «comando»
:RegistrarPedido
armarEstadoPedido(comando :OrdenBD)
ejecutar(obj :Object)
new() «abstraccion»
IntermediarioBDPedido
registrarClienteDePedido(cli :Cliente)
registrarFormaEnvio(fe :FormaEnvio)
registrarMedioTransporte(mt :MedioTransporte)
registrarDetallePedido(detalle :DetallePedido[])
valorObjeto(objeto :Object)
dematerializeWith(obj :Object)
Patrón Command para las
operaciones de la Base de Datos
anadirActualizar() commit()
{ {
commands.add (CommandActualizarDB (obj) ); ordenar()
} for each ICOmmand cmd
cmd.ejecutar()
} deshacer() no está desarrollado,
Transaccion pero debería tener una solución
polimórfica en cada subclase que
commands : List
1..* ICommand conoce de manera única como
commit() deshacer una operación.
añadirEliminar(obj : ObjetoPersistente) 1 ejecutar()
añadirInsertar(obj : ObjetoPersistente) deshacer()
añadirActualizar(obj : ObjetoPersistente)
ordenar()
ObjetoPersistente
CommandDB
ordenar() objeto : ObjetoPersistente
utiliza objetos EstrategiaOrdenacion para commit()
permitir diferentes algoritmos de ejecutar() 1 1 rollback()
ordenación al ordenar los objetos eliminar()
deshacer()
Command guardar()
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Proxy
◎ Consecuencias
◉ Introduce un nivel de indirección para:
1) Un proxy remoto oculta el hecho que objetos residen en diferentes
espacios de direcciones.
2) Un proxy virtual tales como crear o copiar un objeto bajo demanda.
3) Un proxy para protección o las referencias inteligentes permiten realizar
tareas de control sobre los objetos accedidos.
• Patrones de Creación
• Patrones de Estructura
• Patrones de Comportamiento
Materialización Perezosa con un Proxy Virtual
realmente
referencia a una
instancia de ObjetoPersi stente
ProxyFabricante oid : OID
EspecificacionDelProducto
fabricante : IFabricante IFabricante
1 1
getDireccionFabricante() : Direccion getDi reccion()
{
return fabricante.getDireccion() ProxyFabricante
} Fabricante
sujetoReal : IFabricante
(1) Proxy-del direccion
getSujetoReal: IFabricante() 1..* +sujetoReal 1
getDireccion() getDireccion()
{ {
return getSujetoReal().getDireccion() if (sujetoReal == null)
} sujetoReal = FachadaPersistencia.get (oid, Fabricante.class);
return sujetoReal
(2) } (3)
¿Quién crea el Proxy Virtual?
g u a r d a r e l e s ta d o d e l a i te r a c i ó n
e v i ta r l a h i s te r é s i s
c r e a r c o m p u e s to s
It e ra to r B r id g e
e n u m e r a r l o s h ij o s
c o m b in a d a s u s a n d o
C o m p o s ite
a ñ a d ir o p e ra c io n e s d e fi n i r r e c o r r i d o s
a ñ a d i r r e s p o n s a b i l i d a d e s a o b j e to s
V i s i to r
D e c o r a to r
a ñ a d ir o p e ra c io n e s C o m m a n d
c a m b ia r la p ie l e n v e z d e l a s tr ip a s
d e fi n i r l a g r a m á ti c a d e fi n i r l a c a d e n a
F lyw e ig h t
M e d i a to r C h a in o f R e s p o n s a b i li t y
c o m p a r ti r e s tr a te g i a s c o m p a r ti r s ím b o l o s te r m i n a l e s
S tr a te g y
a ñ a d ir o p e r a c io n e s
c o m p a r ti r e s ta d o s
In te r p r e te r g e s ti ó n d e d e p e n d e n c i a s c o m p l e j a s
S ta t e
O b s e rve r
d e fi n i r l o s p a s o s d e u n a l g o r i tm o
T e m p l a te M e th o d s u e le u s a r
P r o to ty p e F a c t o ry M e t h o d
c o n f i g u r a r f á b r i c a s d in á m i c a m e n t e
i m p l e m e n ta d o u s a n d o
A b s tr a c t F a c t o ry
in s t a n c ia ú n i c a
S i n g l e to n in s t a n c ia ú n i c a
F a cad e
Causas comunes de rediseño
Crear un objeto indicando la clase. Abstract factory, Factory Method, Prototype
“
◎ Design Patterns: Elements of Reusable Object-
oriented software. Gamma, Helm, Johnson,
Vlissides
◎ Applying UML and Patterns. Craig Larman
◎ Head First Design Patterns. Freeman &
Freeman
◎ Dive into Design Patterns. Alexander Shvets
◎ https://refactoring.guru/