1 / 51

POO

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). Principiul “inchis-deschis”.

rowdy
Download Presentation

POO

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. POO Proiectarea de clase

  2. 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) POO – Proiectarea de clase

  3. 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 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) 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 POO – Proiectarea de clase

  6. Principiul substituirii • “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) POO – Proiectarea de clase

  7. Principiul substituirii: neconformare 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 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); } POO – Proiectarea de clase

  10. Proiectare prin contract • 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) POO – Proiectarea de clase

  11. Proiectare prin contract ...A::f(...) { //requires p1 (prec.) //ensures q1 (post.) ... } ...B::f(...) { //requires p2 (prec.) //ensures q2 (post.) ... } 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 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; } POO – Proiectarea de clase

  14. Principiul substituirii //requires: true //ensures: latime = 2 * old(latime) //requires: lungime = latime //ensures: latime = 2 * old(latime)) /\ // lungime = latime 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 POO – Proiectarea de clase

  16. Principiul de inversare a dependentelor 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; } POO – Proiectarea de clase

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

  19. Principiul de inversare a dependentelor 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; } 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: } POO – Proiectarea de clase

  22. Sabloane de proiectare (Design Patterns) • intai aplicate in proiectare urbanistica: C. Alexander. A Pattern Language. 1977 • prima contributie in software: 1987, Kent Beck (creatorul lui Extreme Programming) & Ward Cunningham (a scris primul wicki) • contributia majora: Design Patterns: Gamma et al. Elements of Reusable Object-Oriented Software was published, 1994 • cunoscuta ca GoF (Gang of Four) • in functie de scop, clasifica patternurile in • creationale • structurale • comportamentale • pot fi aplicate la nivel de clasa sau obiect POO – Proiectarea de clase

  23. Ce este un sablon de proiectare? • definitia originala a lui Alexander: "Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice“ • Elementele esentiale ale unui pattern (GoF): • nume • problema (si context) • solutie • consecinte • GoF include 23 de sabloane POO – Proiectarea de clase

  24. Formatul (template) unui sablon • nume si clasificare • intentie • cunoscut de asemenea ca • motivatie • aplicabilitate • structura • participanti • colaborari • consecinte • implementare • cod • utilizari cunoscute • sabloane cu care are legatura POO – Proiectarea de clase

  25. Clase cu o singura instanta (Singleton) • Intentia • proiectarea unei clase cu un singur obiect (o singura instanta) • Motivatie • intr-un sistem de operare: • exista un sistem de fisiere • exista un singur manager de ferestre • Aplicabilitate • cand trebuie sa existe exact o instanta • clientii clasei trebuie sa aiba acces la instanta din orice punct bine definit POO – Proiectarea de clase

  26. Clase cu o singura instanta (Singleton) • structura • participant: Singleton • colaborari: clientii clasei POO – Proiectarea de clase

  27. Clase cu o singura instanta (Singleton) • Consecinte • acces controla la instanta unica • reducerea spatiului de nume (eliminarea variab. globale) • permite rafinarea operatiilor si reprezentarii • permite un numar variabil de instante • mai flexibila decat operatiile la nivelde clasa (statice) • Implementare POO – Proiectarea de clase

  28. Clase cu o singura instanta (Singleton) POO – Proiectarea de clase

  29. Clase cu o singura instanta class Singleton { public: static Singleton& instance() {return uniqueInstance;} int getValue() { return i; } void setValue(int x) { i = x; } private: static Singleton uniqueInstance; int i; Singleton(int x) : i(x) { } void operator=(Singleton&); Singleton(const Singleton&); }; POO – Proiectarea de clase

  30. Clase cu o singura instanta Singleton Singleton::s(47); int main() { Singleton& s1 = Singleton::instance(); cout << s1.getValue() << endl; Singleton& s2 = Singleton::instance(); s2.setValue(9); cout << s1.getValue() << endl; return 0; } POO – Proiectarea de clase

  31. 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 POO – Proiectarea de clase

  32. Fabrica de obiecte:: motivatie typedef enum {SEGMID = 1, CERCID} TipFig; POO – Proiectarea de clase

  33. 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); } } POO – Proiectarea de clase

  34. Fabrica de obiecte:: structura POO – Proiectarea de clase

  35. Fabrica de obiecte POO – Proiectarea de clase

  36. 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 POO – Proiectarea de clase

  37. 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 POO – Proiectarea de clase

  38. Fabrica de obiecte:: solutia • definim mai intai clasa de baza ca si clasa abstracta class Figura { public: Figura() { std::cout << "Figura();\n"; } virtual void citeste(std::ifstream&) = 0; }; POO – Proiectarea de clase

  39. 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) POO – Proiectarea de clase

  40. Fabrica de obiecte:: FabricaDeFigBaza class FabricaDeFigBaza { public: typedef Figura* (*DelegatCreareFig)(); FabricaDeFigBaza() { } bool inregistreazaFig(int figId, \ DelegatCreareFig fctCreare); bool elimina(int figId); Figura* creeazaFig(int figId); private: typedef std::map<int, DelegatCreareFig> DelegatMap; DelegatMap delegati_; }; POO – Proiectarea de clase

  41. Fabrica de obiecte :: FabricaDeFigBaza bool FabricaDeFigBaza::inregistreazaFig(int figId, DelegatCreareFig fctCreare) { return delegati_.insert(DelegatMap::value_type(figId, fctCreare)).second; } bool FabricaDeFigBaza::elimina(int figId) { return delegati_.erase(figId) == 1; } POO – Proiectarea de clase

  42. Fabrica de obiecte :: FabricaDeFigBaza Figura* FabricaDeFigBaza::creeazaFig(int figId) { DelegatMap::const_iterator i = delegati_.find(figId); if (i == delegati_.end()) { // nu a gasit throw "ID de figura necunoscut\n"; } // invoca functia de creare return (i->second)(); } POO – Proiectarea de clase

  43. Fabrica de obiecte:: functia de incarcare FabricaDeFigBaza fabricaFig; // global void ContainerFig::incarca(std::ifstream& inp) { // citeste tipul figurii int figId; inp >> figId; while (inp) { //creeaza un obiect vid Figura* pfig = fabricaFig.creeazaFig(figId); // incarca obiectul pfig->citeste(inp); cntnr.push_back(pfig); // citeste tipul noii figuri inp >> figId; } } POO – Proiectarea de clase

  44. Fabrica de obiecte:: un nou tip de figura class Segment : public Figura { public: Segment() { std::cout << "Segment()\n"; } virtual void citeste(std::ifstream&); }; POO – Proiectarea de clase

  45. Fabrica de obiecte:: inregistrarea unui nou tip namespace { Figura* creeazaSegm() { return new Segment; } // Id-ul pentru segment const int SEGMID = 1; // inregistreaza const bool registeredSEGM = fabricaFig.inregistreazaFig(SEGMID, \ creeazaSegm); } POO – Proiectarea de clase

  46. Fabrica de obiecte:: solutia::demo int main() { try { ContainerFig cfb; std::ifstream inp("inp.dat"); cfb.incarca(inp); return 0; } catch (char* msg) { std::cout << msg; } } POO – Proiectarea de clase

  47. Fabrica de obiecte:: solutia::rafinare • declararea fabricii de figuri ca obiect global nu este o solutie prea eleganta • putem defini in schimb o clasa cu o singura instanta POO – Proiectarea de clase

  48. Fabrica cu o singura instanta class FabricaDeFig : public FabricaDeFigBaza { public: static FabricaDeFig& Instanta() {return fabricaFig;} private: static FabricaDeFig fabricaFig; FabricaDeFig() { } void operator=(FabricaDeFig&); FabricaDeFig(const FabricaDeFig&); }; FabricaDeFig FabricaDeFig::fabricaFig; POO – Proiectarea de clase

  49. Fabrica de obiecte :: incarca (rafinat) void ContainerFig::incarca(std::ifstream& inp) { ... while(inP) { //creeaza un obiect vid Figura* pfig = FabricaDeFig::Instanta().creeazaFig(figId); ... } } POO – Proiectarea de clase

  50. Fabrica de obiecte :: inregistrare (rafinat) namespace { Figura* creeazaSegm() { .... } ... // inregistreaza const bool registeredSEGM = FabricaDeFig::Instanta().inregistreazaFig( SEGMID, creeazaSegm ); } POO – Proiectarea de clase

More Related