Sunteți pe pagina 1din 23

POO

Sabloane de proiectare
Fabrica de obiecte
Cuprins
 sabloane de proiectare (software design patterns)
• fabrica de obiecte (Abstract Object Factory)

D. Lucanu POO – Proiectarea de clase 2


Fabrica de obiecte (Abstract Factory)
 intentie
• de a furniza o interfata pentru crearea unei familii de
obiecte intercorelate sau dependente fara a specifica
clasa lor concreta
 aplicabilitate
• un sistem ar trebui sa fie independent de modul in
care sunt create produsele, compuse sau
reprezentate
• un sistem ar urma sa fie configurat cu familii multiple
de produse
• o familie de obiecte intercorelate este proiectata
pentru astfel ca obiectele sa fie utilizate impreuna
• vrei sa furniziei o biblioteca de produse ai vrei sa
accesibila numai interfata, nu si implementarea

D. Lucanu POO – Proiectarea de clase 3


Fabrica de obiecte:: motivatie

Figura ContainerFig

citeste() 1 * incarca()

Segment Cerc

citeste() citeste()

typedef enum {SEGMID = 1, CERCID} TipFig;

D. Lucanu POO – Proiectarea de clase 4


Fabrica de obiecte:: motivatie
void ContainerFig::incarca(std::ifstream& inp)
{
while (inp)
{
// citeste tipul figurii
int tipFig; inp >> tipFig;
// creeaza un obiect vid
Figura* pfig;
switch (tipFig)
{
case SEGMID:
pfig = new Segment;
break;
case CERCID:
pfig = new Cerc;
break; //...
}
pfig->citeste(inp);
}
}

D. Lucanu POO – Proiectarea de clase 5


Fabrica de obiecte:: structura

D. Lucanu POO – Proiectarea de clase 6


Fabrica de obiecte (diagrama din GoF)

D. Lucanu POO – Proiectarea de clase 7


Fabrica de obiecte
 colaborari
• normal se creeaza o singura instanta
 Consecinte
• izoleaza clasele concrete
• simplifica schimbul familiei de produse
• promoveaza consistenta printre produse
• suporta noi timpul noi familii de produse usor
• respecta principiul deschis/inchis
 implementare

D. Lucanu POO – Proiectarea de clase 8


Functii delegat (callback)
 o functie delegat (callback) este o functie care nu este
invocata explicit de programator; responsabilitatea
apelarii este delegata altei functii care primeste ca
parametru adresa functiei delegat
 Fabrica de obiecte utilizeaza functii delegat pentru
crearea de obiecte: pentru fiecare tip este delegata
functia carea creeaza obiecte de acel tip

D. Lucanu POO – Proiectarea de clase 9


Fabrica de obiecte:: solutia
 definim mai intai clasa de baza ca si clasa abstracta

class CFigure
{
public:
virtual void print() const = 0;
virtual void save( ofstream& outFile )
const = 0;
virtual void load( ifstream& inFile ) = 0;
};

D. Lucanu POO – Proiectarea de clase 10


Fabrica de obiecte:: solutia

 definim apoi o fabrica de figuri, adica o clasa care sa


gestioneze tipurile de figuri
• inregistreaza un nou tip de figura (apelata ori de cate
ori se defineste o noua clasa derivata)
• eliminarea unui tip de figura inregistrat (stergerea unei
clase derivate)
• crearea de figuri
 la nivel de implementare utilizam perechi
(IdTipFig, PointerFunctieDeCreareDelegata)

D. Lucanu POO – Proiectarea de clase 11


CAbstractFigFactory

class CAbstractFigFactory
{
public:
typedef CFigure* ( *CreateFigureCallback )();
bool RegisterFigure( int figureId,
CreateFigureCallback CreateFn );
bool UnregisterFigure( int figureId );
CFigure* CreateFigure( int figureId );
private:
typedef map<int, CreateFigureCallback>
CallbackMap;
CallbackMap callbacks_;
};

D. Lucanu POO – Proiectarea de clase 12


CAbstractFigFactory ::RegisterFigure()

bool
CAbstractFigFactory::RegisterFigure
( int figureId,
CreateFigureCallback CreateFn )
{
return
callbacks_.insert( CallbackMap::value_type
( figureId, CreateFn )
).second;
}

D. Lucanu POO – Proiectarea de clase 13


CAbstractFigFactory::UnregisterFigure()

bool
CAbstractFigFactory::UnregisterFigure
( int figureId )
{
return
callbacks_.erase( figureId ) == 1;
}

D. Lucanu POO – Proiectarea de clase 14


CAbstractFigFactory::CreateFigure()

CFigure*
CAbstractFigFactory::CreateFigure
( int figureId )
{
CallbackMap::const_iterator
i = callbacks_.find( figureId );
if ( i == callbacks_.end() )
throw string( "Unknown figure ID" );
return (i->second)();
}

D. Lucanu POO – Proiectarea de clase 15


CFigFactory

class CFigFactory : public CAbstractFigFactory


{
public:
static CFigFactory* getInstance()
{
if ( pInstance == 0 )
pInstance = new CFigFactory();
return pInstance;
}
private:
CFigFactory() { }
static CFigFactory* pInstance;
};

D. Lucanu POO – Proiectarea de clase 16


CContainer
class CContainer
{CContainer
public:
CContainer();
void save( ofstream& outFile ) const;
void load( ifstream& inFile );
void add( CFigure* _pF );
void print() const;

private:
vector<CFigure*> figures;
// vector of pointers to figures
};

D. Lucanu POO – Proiectarea de clase 17


CContainer::load()
void CContainer::load( ifstream& inFile )
{
int figureType;
while ( inFile >> figureType )
{
CFigure* pNewFigure;

pNewFigure = CFigFactory::getInstance()->
CreateFigure( figureType );

pNewFigure->load( inFile );
add( pNewFigure );
}
}

D. Lucanu POO – Proiectarea de clase 18


CContainer::save()
void CContainer::save( ofstream& outFile )
const
{
for ( unsigned int i = 0;
i < figures.size();
i++
)
figures[i]->save( outFile );
}

D. Lucanu POO – Proiectarea de clase 19


Fabrica de obiecte:: un nou tip de figura
class CCircle: public CFigure
{
public:
CCircle();
void print() const;
void save( ofstream& outFile ) const;
void load( ifstream& inFile );
private:
double x, y, r;
};

D. Lucanu POO – Proiectarea de clase 20


Fabrica de obiecte:: inregistrarea unui nou tip
namespace
{
CFigure* CreateCircle()
{
return new CCircle;
}

const int CIRCLE = 1;


const bool registeredCircle =
CFigFactory::getInstance()->
RegisterFigure( CIRCLE, CreateCircle );
}

D. Lucanu POO – Proiectarea de clase 21


Fabrica de obiecte::demo
int main()
{
try
{
ifstream f_in( "in.txt" );
ofstream f_out( "out.txt" );
CContainer tower;
tower.load( f_in );
tower.save( f_out );
}
catch (char* msg)
{
std::cout << msg;
}
}
D. Lucanu POO – Proiectarea de clase 22
Codul din GoF

D. Lucanu POO – Proiectarea de clase 23

S-ar putea să vă placă și