2. ManuelAlejandro Damián
Edsel Barbosa González
José Luis Garza Gallegos
Kevin Roberto Gómez Peralta
Amayelli Itzel Silva Contreras
3. Define una dependencia de uno a muchos entre objetos, de forma que
cuando un objeto cambia de estado se notifica y actualizan
automáticamente todos los objetos.
El objeto observado notifica a sus observadores cada vez que ocurre un
cambio. Después de ser informado de un cambio en el objeto observado,
cada observador concreto puede pedirle la información que necesita para
reconciliar su estado con el de aquél.
Existen de 3 tipos:Creación, Estructurales y de Comportamiento.
Los patrones de comportamiento describen no solamente estructuras de
relación entre objetos o clases sino también esquemas de comunicación
entre ellos y se pueden clasificar en función de que trabajen con clases
(Método Plantilla) u objetos (Cadena de Responsabilidad,Comando,
Iterador, Recuerdo, Observador, Estado, Estrategia,Visitante).
Los observadores están obligados a implementar unos métodos
determinados mediante los cuales el Sujeto es capaz de notificar a sus
observadores suscritos los cambios que sufre para que todos ellos tengan
la oportunidad de refrescar el contenido representado.
4. Este patrón es un patrón de comportamiento. Su
intención es proporcionar a los componentes
una forma flexible de enviar mensajes de
difusión a los receptores interesados.
El patrón Observer es la clave del patrón de
arquitectura ModeloVista Controlador (MVC).
Motivación: Muchas veces un efecto lateral de
partir un sistema en una colección de objetos
relacionados es que necesitamos mantener la
consistencia entre objetos relacionados.
5.
6. Participantes:
Subject: Conoce a sus observadores, Proporciona una
Interfaz para que se suscriban los objetos Observer.
Observer: Define una interfaz para actualizar los objetos
que deben ser notificados de cambios en el objeto
Subject.
ConcreteSubject: Guarda el estado de interés para los
objetos ConcreteObserver, Envía una notificación a sus
observadores cuando cambia su estado.
ConcreteObserver: Mantiene una referencia a un objeto
ConcreteSubject, Guarda el estado que debería
permanecer sincronizado con el objeto observado,
Implementa la interfaz Observer para mantener su estado
consistente con el objeto observado.
7.
8. Las consecuencias de aplicar este patrón pueden ser
tanto beneficiosas como pueden perjudicar algunos
aspectos. Por una parte abstrae el acoplamiento entre
el sujeto y el observador, lo cual es beneficioso ya que
conseguimos una mayor independencia y además el
sujeto no necesita especificar los observadores
afectados por un cambio. Por otro lado, con el uso de
este patrón ocurre que vamos a desconocer las
consecuencias de una actualización, lo cual,
dependiendo del problema, puede afectarnos en
mayor o menor medida (por ejemplo, al rendimiento).
9.
10. Opciones o problemas que se pueden presentar a la
hora de implementar este patrón:
Opción 1º:
Para evitar que el observador concreto tenga una
asociación con el sujeto concreto se puede hacer que
sea una relación bidireccional, evitando así
asociaciones concretas, el problema es que dejaría de
ser una interfaz; pero puede producir problemas si el
lenguaje de programación no soporta la herencia
múltiple. Se podría eliminar la bidireccionalidad de la
asociación pasando el sujeto como parámetro al
método actualizar y ya no se tendría que referenciar el
objeto observado.
11. Si hay muchos sujetos sin observador, la estructura de
los observadores está desaprovechada, para
solucionarlo podemos tener un intermediario que
centralice el almacenamiento de la asociación de cada
sujeto con sus observadores. Para esta solución
creamos ese gestor de observadores usando el patrón
Singleton(Instancia única), ya que nos proporciona
una única referencia y no una por cada sujeto. El
gestor aunque mejora el aprovechamiento del
espacio, hace que se reduzca el rendimiento y se
pierde eficiencia en el método notificar.
12. El responsable de iniciar la comunicación es el
sujeto concreto, pero se puede dar un
problema cuando el objeto concreto está
siendo actualizado de forma continua ya que
debido a esto se tendía que realizar muchas
actualizaciones en muy poco tiempo. La
solución sería suspender temporalmente las
llamadas al método de
actualización/notificación.
13. A la hora de implementar este patrón debemos de ser
cuidadosos cuando un elemento observable
desaparece. En ciertos lenguajes será el gestor de
memoria el que cada cierto tiempo debe de limpiará
las referencias liberadas, pero si un observable que
sigue siendo observado puede no liberarse nunca.
Para solucionar este problema puede crearse una
función “destruir (destroy) “que notifique al gestor
que el elemento observable va a desaparecer y si no
estamos usando la variante del gestor el observable
directamente des-registrará a sus observadores.
14.
15. Problema: Existe una extrema complejidad en el
código cuando se intenta administrar
comportamientos diferentes según una cantidad
de estados diferentes. Asimismo el
mantenimiento de este código se torna
dificultoso, e incluso se puede llegar en algunos
casos puntuales a la incongruencia de estados
actuales por la forma de implementación de los
diferentes estados en el código (por ejemplo con
variables para cada estado).
16. Se implementa una clase para cada estado
diferente del objeto y el desarrollo de cada
método según un estado determinado. El objeto
de la clase a la que le pertenecen dichos estados
resuelve los distintos comportamientos según su
estado, con instancias de dichas clases de
estado. Así, siempre tiene presente en un objeto
el estado actual y se comunica con este para
resolver sus responsabilidades.
Consecuencias: Se debe contemplar la
complejidad comparada con otras soluciones.
17. Context(Contexto): Este integrante define la interfaz con el cliente. Mantiene una
instancia de ConcreteState (Estado Concreto) que define su estado actual
State (Estado):Define una interfaz para el encapsulamiento de la responsabilidades
asociadas con un estado particular de Context.
Subclase ConcreteState:Cada una de estas subclases implementa el
comportamiento o responsabilidad de Context.
18. /*Patrón de diseño Estado - un FSM con dos estados y dos eventos
(lógica de transición distribuida - lógica en las clases derivadas
estatales).*/
#include <iostream>
#include <string>
using namespace std;
//1. Creamos la clase maquina que nos dara el estado en que se
encuentra
class Machine
{
class State *current;
public:
Machine();
void setCurrent(State *s)
{
current = s;
}
void on();
void off();
};
//2. Aqui creamos la clase estado, para saber que esta haciendo
class State
{
public:
virtual void on(Machine *m)
{
cout << " already ONn";
}
virtual void off(Machine *m)
{
cout << " already OFFn";
}
};
void Machine::on()
{
current->on(this);
}
void Machine::off()
{
current->off(this);
}
class ON: public State
{
public:
ON()
{
cout << " ON-ctor ";
};
~ON()
{
cout << " dtor-ONn";
};
void off(Machine *m);
};
//3. En esta parte creamos la classe OFF, para saver en que momento se apaga la
maquina
class OFF: public State
{
public:
OFF()
{
cout << " OFF-ctor ";
};
~OFF()
{
cout << " dtor-OFFn";
};
void on(Machine *m)
{
cout << " going from OFF to ON";
m->setCurrent(new ON());
delete this;
}
};
void ON::off(Machine *m)
{
cout << " going from ON to OFF";
m->setCurrent(new OFF());
delete this;
}
Machine::Machine()
{
current = new OFF();
cout << 'n';
}
19. int main()
{
void(Machine:: *ptrs[])() =
{
Machine::off, Machine::on
};
Machine fsm;
int num;
while (1)
{
cout << "Enter 0/1: "; //Introducimos la combinacion de digitos para
saver el estado
cin >> num;
(fsm. *ptrs[num])();
}
}
20. Problema:
El patrón Strategy aborda problemas que
pueden (o se prevee que puedan) ser
implementados o afrontados de distintas
formas y cuyo interfaz esta bien definido y es
común para dichas formas, pudiendo ser
cualquiera de ellas valida o más deseable en
determinadas situaciones y permitiendo el
cambio entre las distintas estrategias en
tiempo de ejecución.
21.
Factoriza aspectos comunes de una familia de
algoritmos y utilizarlos en las clases base de la
jerarquía.
Aumenta cohesión del cliente
Sistematiza el uso de implementaciones alternativas
El cliente es el responsable de crear estrategias, por
tanto debe comprender las posibilidades que ofrecen,
esto es, debe ser relevante para el contexto del
cliente.
Menor eficiencia. Aumenta el número de objetos
creados.
22.
23.
24. public interface Strategy {
public void execute();
}
public class ConcreteStrategyA implements Strategy {
public void execute() { ... }
}
public class ConcreteStrategyB implements Strategy {
public void execute() { ... }
}
public class Context {
private Strategy _strategy;
publicContext (Strategy s) { _strategy = s; }
publicContext () { _strategy = newConcreteStrategyA(); }
public void execute() { _strategy.execute(); }
}
public class Client {
public static void main (String args[]) {
Context context = new Context(new ConcreteStrategyA());
context.execute();
}
}
25. La solución que el patrón estrategia supone para
este escenario pasa por encapsular los distintos
algoritmos en una jerarquía y que el cliente trabaje
contra un objeto intermediario contexto.
El cliente puede elegir el algoritmo que prefiera de
entre los disponibles, o el mismo contexto puede ser
el que elija el más apropiado para cada situación.
26. Dentro del marco de la programación orientada
a objetos, el patrón Template Method (Método
Plantilla o Método Modelo en español) es
un patrón de diseño enmarcado dentro de los
llamados patrones de comportamiento, que se
caracteriza por la definición, dentro de una
operación de una superclase, de los pasos de un
algoritmo, de forma que todos o parte de estos
pasos son redefinidos en las subclases herederas
de la citada superclase.
27. Permitir que ciertos pasos de un algoritmo
definido en una operación de una superclase,
sean redefinidos en las subclases sin
necesidad de tener que sobrescribir la
operación entera.
28. La utilización del patrón Método Plantilla es adecuada en los
siguientes casos:
• Cuando contamos con un algoritmo con varios pasos que no
cambian, de modo que dichos pasos invariantes serían
implementados en una superclase, dejando la implementación de
los pasos que cambian para las subclases.
• Para evitar la replicación de código mediante generalización: se
factoriza el comportamiento común de varias subclases en una
única superclase.
• Para controlar las extensiones de las subclases. El Método Plantilla
utiliza métodos especiales (métodos de enganche o hooks) en
ciertos puntos, siendo los únicos puntos que pueden ser redefinidos
y, por tanto, los únicos puntos donde es posible la extensión.
29. Se muestra a continuación la estructura que
sigue el patrón Método Plantilla:
Participantes:
ClaseAbstracta: proporciona la definición de
una serie de operaciones primitivas
(normalmente abstractas) que implementan los
pasos de un algoritmo y que serán definidas en
las subclases.
Se encarga también de la implementación de un
método desde el cual son invocadas, entre
otras, las operaciones primitivas. Dicho método
actúa a modo de plantilla, de ahí el nombre de
este patŕon, definiendo la secuencia de
operaciones de un algoritmo.
Clase Concreta: implementa las operaciones
primitivas definidas en la clase abstracta de la
cual hereda, quedando así determinado el
comportamiento específico del algoritmo
definido en el método plantilla, para cada
subclase.
30. • La utilización de este patrón es fundamental a la hora de reutilizar
código.
• Se invierte el control: en este caso la superclase es la encargada de
llamar a las operaciones definidas en las subclases.
• Distinción entre:
• Operaciones primitivas (implementadas en la superclase)
• Operaciones de enganche o hooks (proporcionan un código por
defecto que puede ser refinado en las subclases).
Cabe destacar que los métodos plantilla juegan un papel clave en
las bibliotecas de clases ya que permiten extraer el
comportamiento común de las clases de la biblioteca. Otro uso
común de este patrón se da en la creación de sistemas de plugins
gracias principalmente a la utilización de las anteriormente citadas
operaciones de enganche (hooks).
31. A la hora de proceder a implementar este
patrón, resulta de interés tener en cuenta los
seguintes detalles:
• Es recomendable declarar las operaciones
primitivas de tal forma que sólo puedan ser
llamadas por el método plantilla (protected si se
trabaja con el lenguaje de programación Java)
• Debe reducirse en la medida de lo posible el
número de operaciones primitivas que van a ser
invocadas desde el método plantilla. De este
forma se reducirá la complejidad de las subclases
y resultará menos tediosa su implementación.
32. Se muestra a continuación un ejemplo de
implementación del patrón Método Plantilla.
En el se intenta ilustrar a grandes rasgos el
modo de desplazamiento de un automóvil
que, básicamente, se puede simplificar en:
acelerar, cambiar de marcha y frenar. El
proceso de acelerar y frenar se puede
considerar que es idéntico en todos los
automóviles, sin embargo la forma de cambiar
de marcha varia de unos a otros según sean
autos con cambio manual o autos con cambio
automático.
De acuerdo con esto, podemos considerar una
superclase Automóvil en la cual se define un
método plantilla Desplazar desde el cual se
llama a la operación primitiva CambiarMarcha
que es implementada de una forma en la
subclase "AutomovilManual", y de otra forma
en la subclase "AutomovilAutomatico".
33. De acuerdo con esto,
podemos considerar una
superclase Automóvil en
la cual se define un
método plantilla
Desplazar desde el cual
se llama a la operación
primitiva CambiarMarcha
que es implementada de
una forma en la subclase
"AutomovilManual", y de
otra forma en la subclase
"AutomovilAutomatico".
34. Problema: Uno de los principales problemas que
presenta este diseño, es querer que una
operaciónno esté en la jerarquía, sino que esté
fuera, para que cada vez que haya un cambio no
haya que cambiarlo todo. Esta opción, además,
obliga a tener que definir cada operación que
necesite el cliente en cada clase de la jerarquía, y
a que los clientes conozcan operaciones que no
necesita, ya que sólo interesa que conozca las
que va a manejar.
35. Problema: Uno de los principales problemas que
presenta este diseño, es querer que una
operación no esté en la jerarquía, sino que esté
fuera, para que cada vez que haya un cambio no
haya que cambiarlo todo. Esta opción, además,
obliga a tener que definir cada operación que
necesite el cliente en cada clase de la jerarquía, y
a que los clientes conozcan operaciones que no
necesita, ya que sólo interesa que conozca las
que va a manejar.
36. Es un patrón de comportamiento, que
permite definir una operación sobre objetos
de una jerarquía de clases sin modificar las
clases sobre las que opera. Representa una
operación que se realiza sobre los elementos
que conforman la estructura de un objeto.
37. Es fácil añadir nuevas operaciones a un
programa utilizandoVisitantes, ya que el
visitante contiene el código en lugar de cada
una de las clases individuales.Además, los
visitantes pueden recoger las operaciones
relacionadas en una sola clase en lugar de
obligar a cambiar o derivar clases para
agregar estas operaciones. Esto puede hacer
al programa más sencillo de escribir y
mantener.
38. Visitante (Visitor): Declara una operación de visita para cada elemento concreto en la
estructura de objetos, que incluye el propio objeto visitado
Visitante Concreto (ConcreteVisitor1/2): Implementa las operaciones del visitante y acumula
resultados como estado local
Elemento (Element): Define una operación “Accept” que toma un visitante como argumento
Elemento Concreto (ConcreteElementA/B): Implementa la operación “Accept”
39. 1.- Agregar un método accept (visitantes) a la jerarquía "elemento"
2.- Crear una base de clase "turista" con un método de visita () para cada tipo de "elemento"
3.- Crear un "visitante" que es una clase derivada para cada "operación" para hacerlo en
"elementos"
4.- Cliente crea objetos "visitantes" y pasa a cada uno a aceptar una llamada
EJEMPLO