Capítulo VI: DOO
II Parte
[email protected] (C-305)
Adaptador(GoF)
Problema: ¿Cómo resolver interfaces incompatibles, o
proporcionar una interfaz estable para componentes
parecidos con diferentes interfaces?
Solución: Convierta la interfaz original de una componente
en otra, mediante un objeto adaptador intermedio.
El propósito de este patrón es convertir la interfaz de
una clase en otra interfaz que es la que esperan los
clientes.
Ejemplo de Fibonacci
Ejemplo Adaptador
Un generador de la serie de Fibonacci ha sido dado.
Adaptarlo para emplear los algoritmos dados por las STL.
#ifndef FIBONACCIGENERATOR_H
#define FIBONACCIGENERATOR_H
class FibonacciGenerator {
int n;
int val[2];
public:
FibonacciGenerator() : n(0) { val[0] = val[1] = 1; }
int operator()() {
int result = n > 2 ? val[0] + val[1] : 1;
++n;
val[0] = val[1];
val[1] = result;
return result;
}
int count() { return n; }
};
#endif // FIBONACCIGENERATOR_H ///:~
21nnnFFF11235813...Ejemplo Adaptador
Código de test
imprimir);
=IAdaptadorFibonacci::factoriaFibonacci(numeroFibo);
int main()
{
const unsigned numeroFibo = 20;
IAdaptadorFibonacci *pAdaptadorFibo
cout << "Tabla de Fibonacci" <<endl;
cout << "------------------" <<endl;
for_each(pAdaptadorFibo->getSerie().begin(),pAdaptadorFibo->getSerie().end(),
//Ver GRASP "No hable con extraños" y el código maduro
return 0;
}
void imprimir(unsigned numFibo)
{
}
static unsigned indice;
cout << indice++ << ": " << numFibo <<endl;
21nnnFFF...138532111Ejemplo Adaptador
Ejemplo Adaptador
#include <vector>
#include "FibonacciGenerator.h"
class IAdaptadorFibonacci
{
public:
virtual std::vector<unsigned> & getSerie() = 0;
};
class AdaptadorFibonacci: public IAdaptadorFibonacci
static IAdaptadorFibonacci
*factoriaFibonacci(unsigned grado);
FibonacciGenerator f;
unsigned tamanyo;
std::vector<unsigned> elVectorFibon;
friend class IAdaptadorFibonacci;
AdaptadorFibonacci(unsigned num):
tamanyo(num) {
{
for (unsigned i=0;i<=tamanyo;i++)
public:
};
elVectorFibon.push_back(f());
}
virtual std::vector<unsigned> & getSerie()
{return elVectorFibon;}
Problema 3: Tabla de números primos
En el cuadro se entrega el código sobre un generador de números
primos. Se trata de diseñar un componente tal que el cliente le
entregue el número límite de números primos, n, y el servidor retorne
con un vector que contenga los n primeros números primos. En la
figura se presenta el resultado del cliente. Se pide:
1. Realizar ingeniería inversa sobre el generador de números primos.
2. Obtener el diagrama de clase de diseño, DCD, así como el diagrama
de secuencia del componente servidor.
Implementación del cliente en C++.
Implementación de las clases en C++ del componente servidor.
3.
4.
Problema 3: Tabla de números primos
do {
#ifndef NUMEROSPRIMOS_H
#define NUMEROSPRIMOS_H
class NumerosPrimos {
unsigned elUltimoPrimo;
unsigned elNumero;
public :
NumerosPrimos() : elUltimoPrimo(1) { elNumero = elUltimoPrimo+1;}
unsigned getSiguientePrimo()
{
for ( unsigned divisor = 2;elNumero % divisor != 0; divisor++ ) ;
if (divisor == elNumero)
return (elUltimoPrimo);
}
};
#endif
else
elNumero++;
} while ( elUltimoPrimo != elNumero );
elNumero++;
elUltimoPrimo = elNumero;
Problema 3: Tabla de números primos
Problema 3: Tabla de números primos
Problema 3: Tabla de números primos
Problema 3: Tabla de números primos
#include <iostream> #include "AdaptadorNumerosPrimos.h" #include <numeric> #include <algorithm> IAdaptadorNumerosPrimos* IAdaptadorNumerosPrimos::metodoFabricacion(unsigned limite) { return (new AdaptadorNumerosPrimos(limite)); } using namespace std; void imprimir(unsigned); int main() { unsigned elLimiteNumerosPrimos; cout<<"Cuantos numeros primos desea que aparezcan : "; cin >> elLimiteNumerosPrimos; IAdaptadorNumerosPrimos *pAdaptadorNumPrimos = IAdaptadorNumerosPrimos::metodoFabricacion(elLimiteNumerosPrimos); cout << endl <<"Tabla de Numeros Primos" <<endl; cout << "-----------------------" <<endl; for_each(pAdaptadorNumPrimos->getNumerosPrimos().begin(), pAdaptadorNumPrimos->getNumerosPrimos().end(),imprimir); delete pAdaptadorNumPrimos; return 0; } void imprimir(unsigned numPrimo) { static unsigned indice; cout.width(5); cout << numPrimo; if(++indice % 10 == 0) cout << endl; } Problema 3: Tabla de números primos
#include <vector>
#include "NumerosPrimos.h"
class IAdaptadorNumerosPrimos
{
public:
virtual std::vector<unsigned> & getNumerosPrimos() = 0;
static IAdaptadorNumerosPrimos *metodoFabricacion(unsigned);
};
class AdaptadorNumerosPrimos: public IAdaptadorNumerosPrimos
{
NumerosPrimos elGenerador;
unsigned elLimite;
std::vector<unsigned> elVectorNumerosPrimos;
friend class IAdaptadorNumerosPrimos;
AdaptadorNumerosPrimos(unsigned num): elLimite(num)
for (unsigned i=1;i<=elLimite;i++)
public:
virtual std::vector<unsigned> & getNumerosPrimos()
};
(elGenerador.getSiguientePrimo());
}
{return elVectorNumerosPrimos;}
{
elVectorNumerosPrimos.push_back
Ejemplo 6.13
La aplicación de Respuesta en Frecuencia no depende sólo
del algoritmo de calcular el módulo y argumento de un
filtro, sino también de su visualización en un diagrama de
Bode. Realizar un diseño para el paquete de representación
gráfica.
Ejemplo 6.13
Solución NTGraph. Es un punto caliente (dependencia
tecnológica, prestaciones futuras)
Patrón VP y Adaptador GoF
Ejemplo 6.13
#include "../../ntgraph.h"
//Tipos de visualizadores
enum PlataformaVisual{NTGRAPH} ;
class IAdaptadorVisualizar
{
public:
virtual void InicializarPlotXY(void) = 0;
virtual void PintarPlotXY(float,float,float, double *)= 0;
//Factoria de Visualizadores
static IAdaptadorVisualizar *factoriaVisualizadores(enum
PlataformaVisual,CNTGraph *p1 = NULL);
};
class AdaptadorVisualCNTGraph : public IAdaptadorVisualizar
{
public:
};
CNTGraph *graph;
AdaptadorVisualCNTGraph(CNTGraph *gr): graph(gr){}
friend class IAdaptadorVisualizar;
virtual void InicializarPlotXY(void);
virtual void PintarPlotXY(float,float,float, double *);
Factoría (GRASP)
de
cuando
los objetos
Problema: ¿Quién debe ser responsable de la
existen
creación
consideraciones especiales, como una lógica de
creación compleja, el deseo de separar
las
responsabilidades de la creación para manejar la
cohesión, etc.?
Solución: Crear un objeto de Fabricación Pura
denominado Factoría que maneje la creación.
Ejemplo: Juego del Pang
Disparo* d=0;
if(h.GetNumBonus()==1)
else if(h.GetNumBonus()>=2)
else
Disparo* Factoria::CrearDisparo(Hombre h)
{
}
Vector2D pos=h.GetPos();
d->SetPos(pos.x,pos.y);
return d;
d=new Gancho;
d=new GanchoEspecial;
d=new Lanza;
void Mundo::Tecla(unsigned char key)
{
switch(key) {
}
case ' ': if(disparos.GetNumero()<MAX_DISPAROS){
}
Disparo* d=Factoria::CrearDisparo(hombre);
disparos.Agregar(d);
}
break;
Factoría (GRASP)
Cuando se hace VP ¿ quién debe de tener la responsabilidad
de crear la instancia adecuada?
El paquete ‘no’, excede de sus responsabilidades.
Es un decisión externa
Factoría: lectura de fuente externa y cargar la instancia de la
clase adecuada de forma dinámica.
Ventajas de las Factorías
Separación de responsabilidades en la creación compleja en objetos
de apoyo cohesivo.
Ocultan la lógica de creación potencialmente compleja
Permite introducir estrategias para mejorar el rendimiento de la
gestión de la memoria, como objetos caché o de reciclaje.
Factoría Abstracta (GoF)
Se emplea cuando:
un sistema debe ser independiente de cómo se crean, componen y representan
sus productos.
un sistema debe ser configurado como una familia de productos entre varios.
quiere proporcionar una biblioteca de clases de productos y sólo quiere revelar
sus interfaces, no sus implementaciones.
Factoría Abstracta (GoF)
Los roles desempeñados son:
Cliente: sólo usa interfaces declarados por las clases de Fabricación Abstracta y Productos
Abstractos
Producto Abstracto: declara una interfaz para un tipo de objeto (p.ej. IClaseA)
Producto Concreto: define un objeto producto para que sea creado por la Factoría
correspondiente. Implementa la interfaz de Producto Abstracto.
Factoría Abstracta: declara una interfaz para operaciones que crean objetos productos abstractos
Factoría Concreta: implementa las operaciones para crear objetos producto concretos
Método de Fabricación (GoF)
Se define una interfaz de factoría para crear los objetos, pero se deja que sean las
subclases quienes decidan qué clase instanciar
Los roles que se desempeñan en este patrón son:
Producto: Interfaz de los objetos que crea el método de fabricación
ProductoConcreto: Realización de la interfaz Producto
Factoría: Declara el servicio de MétodoFabricación que retorna un objeto de
tipo producto abstracto
FactoríaConcreto: redefine el método de fabricación para devolver una instancia
de un ProductoConcreto
Ejemplo de interfaz visto capítulo 4
Ejemplo de interfaz
#ifndef _INOMBRE_INC_
#define _INOMBRE_INC_
enum Plataforma{ESTANDAR_STL, ESTILO_C, CADENA_MFC};
class INombre {
public:
virtual
Comentarios de: Capítulo VI: DOO - II Parte (0)
No hay comentarios