Sunteți pe pagina 1din 22

POO

Proiectarea de clase
Cuprins
 principiul inchis-deschis
 principiul substituirii
 principiul de inversare a dependentelor
 sabloane de proiectare (software design patterns)
• clase cu o singura instanta (Singleton)
• fabrica de obiecte (Abstract Object Factory)

D. Lucanu POO – Proiectarea de clase 2


Principiul “inchis-deschis”
 “Entitatile software (module, clase, functii etc.) trebuie sa
fie deschise la extensii si inchise la modificare”
(Bertrand Meyer, 1988)

 “deschis la extensii” = comportarea modulului poate fi


extinsa pentru a satisface noile cerinte

 “inchis la modificare” = nu este permisa modificarea


codului sursa

D. Lucanu POO – Proiectarea de clase 3


Principiul “inchis-deschis” : exemplu

Figura ContainerFig

citeste() 1 * incarca()

Segment Cerc

citeste() citeste()

D. Lucanu POO – Proiectarea de clase 4


Principiul “inchis-deschis”: neconformare
void ContainerFig::incarca(std::ifstream& inp)
{
while (inp)
{
int tipFig; Figura* pfig;
inp >> tipFig;
switch (tipFig)
{
case SEGMID:
...
case CERCID:
...
}
}
}
 O solutie: Fabrica de figuri (… un pic mai tarziu)

D. Lucanu POO – Proiectarea de clase 5


Principiul “inchis-deschis”: conventii
 Declara toate datele membre private
• altfel:
• Schimbarea tipului datei implica schimbarea
functiilor care o utilizeaza
• in plus, nu avem incapsulare
 Fara variabile globale
• O alternativa: clase cu membri statici

D. Lucanu POO – Proiectarea de clase 6


Principiul substituirii
 [A se vedea si prezentarea privind Principiile POO]

 “Functiile care utilizeaza pointeri sau referinte la clasa de


baza trebuie sa fie apte sa utilizeze obiecte ale claselor
derivate fara sa le cunoasca”

care parafrazeaza

 “Daca pentru fiecare obiect o de tip S exista un obiect o’


de tip T astfel incat, pentru toate programele P definite in
termenii lui T, comportarea lui P nu se schimba daca
substituim o cu o’, atunci S este un subtip al lui T.”
(Barbara Liskov, 1988)

D. Lucanu POO – Proiectarea de clase 7


Principiul substituirii: neconformare

Dreptunghi Autovehicul

dubleazaLatime() merge()

Patrat AutovehiculCuGabaritDepasit

dubleazaLatime() merge()

D. Lucanu POO – Proiectarea de clase 8


Principiul substituirii: neconformare
class Dreptunghi {
public:
virtual void dubleazaLatime();
virtual int aria();
protected:
int latime, lungime;
}
Daca dr.aria = d, dupa dr.dubleazaLatime(); avem dr.aria = 2*d

class Patrat : public Dreptunghi {


public:
virtual void dubleazaLatime(int);
virtual int aria();
}
Daca pat.aria = p, dupa pat.dubleazaLatime(); avem pat.aria = 4*p
D. Lucanu POO – Proiectarea de clase 9
Principiul substituirii: neconformare
void Drepunghi::dubleazaLatime() {
latime *= 2;
}
void Patrat::dubleazaLatime() {
latime *= 2;
lungime *= 2;
}
void g(Dreptunghi& d) {
int aria1 = d.aria();
d.dubleazaLatime();
assert(d.aria() = 2*aria1);
}

D. Lucanu POO – Proiectarea de clase 10


Proiectare prin contract
Obligatii Beneficii

Client trebuie sa asigure poate beneficia de pe


preconditia urma postconditiei

Prestator trebuie sa asigure poate presupune


Servicii postconditia preconditia

 Contractele in mostenire
• precizeaza pre- si post-conditiile pentu fiecare metoda
• “cand se redefineste o metoda intr-o clasa derivata,
preconditia se inlocuieste prin o conditie mai slaba iar
postconditia prin una mai tare.” (Bertrand Mayer,
1988)
D. Lucanu POO – Proiectarea de clase 11
Proiectare prin contract
...A::f(...)
{
//requires p1 (prec.) A
//ensures q1 (post.)
... f()
}

...B::f(...)
{
B
//requires p2 (prec.)
//ensures q2 (post.)
... f()
}

D. Lucanu POO – Proiectarea de clase 12


Proiectare prin contract
A a; B b;
 b poate fi utilizat oriunde a este utilizat

• b.f() poate fi apelata in orice stare in care a.f() este


apelata, deci b.f() necesita (requires) o conditie mai
slaba
• daca p1, atunci p2
• starile produse de b.f() satisfac proprietatile
satisfacute de starile corespunzatoare produse de
a.f(), deci b.f() asigura (ensures) o conditie mai tare
decat a.f()
• daca q2, atunci q1

D. Lucanu POO – Proiectarea de clase 13


Proiectare prin contract
void Dreptunghi::dubleazaLatime(){
//requires: true
//ensures: latime = 2 * old(latime) /\
// lungime = old(lungime)
latime *= 2;
}

void Patrat::dubleazaLatime(){
//requires: lungime = latime
//ensures: latime = 2 * old(latime) /\
// lungime = latime
latime *= 2;
lungime *= 2;
}

D. Lucanu POO – Proiectarea de clase 14


Principiul substituirii

Dreptunghi

//requires: true
dubleazaLatime() //ensures: latime = 2 * old(latime)

Patrat

dubleazaLatime() //requires: lungime = latime


//ensures: latime = 2 * old(latime)) /\
// lungime = latime

D. Lucanu POO – Proiectarea de clase 15


Principiul de inversare a dependentelor
 A. “Modulele de nivel inalt nu trebuie sa depinda de
modulele de nivel jos. Amandoua trebuie sa depinda de
abstractii.”

 B. “Abstractiile nu trebuie sa depinda de detalii. Detaliile


trebuie sa depinda de abstractii.”

 programele OO bine proiectate inverseaza dependenta


structurala de la metoda procedurala traditionala
• metoda procedurala: o procedura de nivel inalt
apeleaza o procedura de nivel jos, deci depinde de ea

D. Lucanu POO – Proiectarea de clase 16


Principiul de inversare a dependentelor

aprinde()
stinge()

: Top Package::Buton : Top Package::Lampa

Lampa 1 1 Buton

D. Lucanu POO – Proiectarea de clase 17


Principiul de inversare a dependentelor
class Lampa {
public:
void aprinde();
void stinge();
}
class Buton {
public:
Buton(Lampa& plampa) : lampa(&plampa) {}
void detecteaza();
private:
Lampa *lampa;
}

D. Lucanu POO – Proiectarea de clase 18


Principiul de inversare a dependentelor
void Buton::detecteaza()
{
bool stare = getStareFizica();
if (stare)
lampa->aprinde();
else
lampa->stinge();
}

D. Lucanu POO – Proiectarea de clase 19


Principiul de inversare a dependentelor

ClientButon 1 1 Buton

Lampa ButonImplementare

D. Lucanu POO – Proiectarea de clase 20


Principiul de inversare a dependentelor
class ClientButon {
public:
virtual void aprinde() = 0;
virtual void stinge() = 0;
}
class Buton {
public:
Buton(ClientButon& pclient) : client(&pclient) {}
void detecteaza();
virtual bool getStare() = 0;
private:
ClientButon *client;
}

D. Lucanu POO – Proiectarea de clase 21


Principiul de inversare a dependentelor
class Lampa : public ClientButon {
public:
virtual void aprinde();
virtual void stinge();
}
class ButonImpl : Buton {
public:
ButonImpl(ClientButon& pclient) : client(&pclient)
{}
virtual bool getStare();
private:

D. Lucanu POO – Proiectarea de clase 22

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