15
1 1. Paradigma POO. Mesaje şi responsabilităţi Paradigme de programare este un set de concepte, modele si practici care descriu esenta programarii Programare structurata (functionala) = un program este conceput pe baza unei secvente de functii, fara a avea o stare Programare orientata obiect = programele sunt vazute ca fiind niste colectii de obiecte care interactioneaza unele cu altele Mesaje si responsabilitati Membrii unei comunități orientată-obiect comunica intre ei . Următorul principiu important explică utilizarea de mesaje pentru a iniția o acțiune: Acțiune este inițiată în programarea orientată pe obiecte prin transmiterea unui mesaj de la un agent (un obiect), responsabil pentru acțiunile. Mesajul codifică cererea de acțiune și este însoțită de orice informații suplimentare (argumente / parametri) necesare pentru îndeplinirea cererii. Receptorul este obiectul la care este trimis mesajul. Dacă receptorul acceptă mesajul, acceptă responsabilitatea de a efectua acțiunea indicată. Ca răspuns la un mesaj, receptorul va efectua o metodă pentru a satisface cererea Există unele probleme important de subliniat aici: • Clientul trimite cererea nu trebuie să cunoască mijloacele prin care cererea este efectuat. În acest vom vedea principiul de informare ascunde. • Un alt principiu implicit în mesajul de trecere este ideea de a găsi pe altcineva pentru a face munca de exemplu reutilizarea componentelor care ar fi putut fi scrise de altcineva. • interpretarea mesajului este determinată de către receptor și poate varia în funcție de diferite receptoare. De exemplu, dacă te-a trimis mesajul "flori livrare" la un prieten, ea, probabil, va fi înțeles ceea ce a fost necesar și flori s-ar mai fi fost livrate, dar metoda a folosit ar fi fost foarte diferită de cea utilizată de florar • În programarea orientată pe obiecte, comportamentul este descris în termeni de responsabilități. • cererile Clientului indică doar rezultatul dorit. Receptoarele sunt liberi să urmărească orice tehnica care atinge rezultatele dorite • gândire în acest fel permite o mai mare independență între obiecte. • Astfel, obiectele au responsabilități pe care sunt dispuși să-și îndeplinească, la cerere. Colectarea de responsabilități asociate cu un obiect este adesea numit protocol 2. Paradigma POO. Abstracţii Paradigma POO Concepte: 1.Clasa - implementare a unui TAD 2.Obiect = instanta a unei clase 3.Metoda = implementarea unei operatii din interfata TAD (mesaj = apel al metodei –> interactiune intre obiecte) Caracteristici: 1.Incapsulare (date + operatii) ascunderea informatiei protectia informatiei consistenta datelor 2.Mostenire reutilizarea codului 3.Polimorfism = capacitatea unei entitati de a reactiona diferit in functie de starea sa. Programarea orientata pe obiecte este o metoda de implementare in care programele sunt organizate ca ansamble de obiecte ce coopereaza intre ele, fiecare obiect reprezentand instanta unei clase; fiecare clasa apartine unei ierarhii de clase in cadrul careia clasele sunt legate prin relatii de mostenire. Aceasta definitie cuprinde trei parti importante, si anume: obiectele si nu algoritmii sunt blocurile logice fundamentale; fiecare obiect este o instanta a unei clase. Clasa este o descriere a unei multimi de obiecte caracterizate prin structura si comportament similare. clasele sunt legate intre ele prin relatii de mostenire. Un limbaj de programare care ofera suport pentru utilizarea claselor si a obiectelor, dar care nu are implementat mecanismul relatiilor de mostenire intre clase este un limbaj de programare bazat pe obiecte.

APPOO Teme Evaluare

Embed Size (px)

DESCRIPTION

APPOO Teme Evaluare

Citation preview

Page 1: APPOO Teme Evaluare

1

1. Paradigma POO. Mesaje şi responsabilităţi Paradigme de programare este un set de concepte, modele si practici care descriu esenta programarii

– Programare structurata (functionala) = un program este conceput pe baza unei secvente de functii, fara a avea o stare

– Programare orientata obiect = programele sunt vazute ca fiind niste colectii de obiecte care interactioneaza unele cu altele

Mesaje si responsabilitati Membrii unei comunități orientată-obiect comunica intre ei . Următorul principiu important explică utilizarea de mesaje pentru a iniția o acțiune: Acțiune este inițiată în programarea orientată pe obiecte prin transmiterea unui mesaj de la un agent (un obiect), responsabil pentru acțiunile. Mesajul codifică cererea de acțiune și este însoțită de orice informații suplimentare (argumente / parametri) necesare pentru îndeplinirea cererii.

• Receptorul este obiectul la care este trimis mesajul. Dacă receptorul acceptă mesajul, acceptă responsabilitatea de a efectua acțiunea indicată. Ca răspuns la un mesaj, receptorul va efectua o metodă pentru a satisface cererea

• Există unele probleme important de subliniat aici: • • Clientul trimite cererea nu trebuie să cunoască mijloacele prin care cererea este efectuat. În acest

vom vedea principiul de informare ascunde. • • Un alt principiu implicit în mesajul de trecere este ideea de a găsi pe altcineva pentru a face munca

de exemplu reutilizarea componentelor care ar fi putut fi scrise de altcineva. • • interpretarea mesajului este determinată de către receptor și poate varia în funcție de diferite

receptoare. De exemplu, dacă te-a trimis mesajul "flori livrare" la un prieten, ea, probabil, va fi înțeles ceea ce a fost necesar și flori s-ar mai fi fost livrate, dar metoda a folosit ar fi fost foarte diferită de cea utilizată de florar

• • În programarea orientată pe obiecte, comportamentul este descris în termeni de responsabilități. • cererile Clientului indică doar rezultatul dorit. Receptoarele sunt liberi să urmărească orice tehnica care atinge rezultatele dorite • gândire în acest fel permite o mai mare independență între obiecte. • Astfel, obiectele au responsabilități pe care sunt dispuși să-și îndeplinească, la cerere. Colectarea de responsabilități asociate cu un obiect este adesea numit protocol

2. Paradigma POO. Abstracţii Paradigma POO Concepte: 1.Clasa - implementare a unui TAD 2.Obiect = instanta a unei clase 3.Metoda = implementarea unei operatii din interfata TAD (mesaj = apel al metodei –> interactiune intre obiecte) Caracteristici: 1.Incapsulare (date + operatii) ascunderea informatiei ⇒protectia informatiei ⇒consistenta datelor 2.Mostenire ⇒reutilizarea codului 3.Polimorfism = capacitatea unei entitati de a reactiona diferit in functie de starea sa. Programarea orientata pe obiecte este o metoda de implementare in care programele sunt organizate ca ansamble de obiecte ce coopereaza intre ele, fiecare obiect reprezentand instanta unei clase; fiecare clasa apartine unei ierarhii de clase in cadrul careia clasele sunt legate prin relatii de mostenire. Aceasta definitie cuprinde trei parti importante, si anume:

• obiectele si nu algoritmii sunt blocurile logice fundamentale; • fiecare obiect este o instanta a unei clase. Clasa este o descriere a unei multimi de obiecte

caracterizate prin structura si comportament similare. • clasele sunt legate intre ele prin relatii de mostenire.

Un limbaj de programare care ofera suport pentru utilizarea claselor si a obiectelor, dar care nu are implementat mecanismul relatiilor de mostenire intre clase este un limbaj de programare bazat pe obiecte.

Page 2: APPOO Teme Evaluare

2

Programarea bazata pe clase si pe obiecte, care nu face uz de relatia de mostenire se mai numeste programare cu tipuri de date abstracte. Important: Trebuie sa intelegem ca prin simpla invatare a unui limbaj care suporta programarea orientata pe obiecte NU invatam automat sa programam corect conform modelului obiectual! Pentru a invata acest lucru trebuie sa intelegem si sa aplicam conceptele si mecanismele care stau la baza acestui model. Si tocmai acest lucru ni-l propunem. Concluzii

Ideea POO (Programare Orientată Obiectual) este de a crea programele ca o colecție de obiecte, unități individuale de cod care interacționează unele cu altele, în loc de simple liste de instrucțiuni sau de apeluri de proceduri . Obiectele POO sunt de obicei reprezentări ale obiectelor din viața reală (domeniul problemei), astfel încât programele realizate prin tehnica POO sunt mai ușor de înțeles, de depanat și de extins decât programele procedurale. Aceasta este adevărată mai ales în cazul proiectelor software complexe și de dimensiuni mari, care se gestionează făcând apel la ingineria programării. Abstractizarea este una din caile fundamentale prin care noi, oamenii, ajungem sa intelegem si sa cuprindem complexitatea. O abstractiune buna este cea care scoate in evidenta toate detaliile semnificative pentru perspectiva din care este analizat un obiect, suprimand sau estompand toate celelalte caracteristici ale obiectului. In contextul programarii orientate pe obiecte, Booch ne ofera urmatoarea definitie a abstractiunii [Boo94]: O abstractiune exprima toate caracteristicile esentiale ale unui obiect, care fac ca acesta sa se distinga de alte obiecte; abstractiunea ofera o definire precisa a granitelor conceptuale ale obiectului, din perspectiva unui privitor extern. In procesul de abstractizare atentia este deci indreptata exclusiv spre aspectul exterior al obiectului, adica spre comportarea lui, ignorand implementarea acestei comportari. Cu alte cuvinte abstractizarea ne ajuta sa delimitam ferm "CE face obiectul" de "CUM face obiectul ceea ce face". Comportarea unui obiect se caracterizeaza printr-o suma de servicii sau resurse pe care el le pune la dispozitia altor obiecte. Un asemenea comportament, in care un obiect, numit server, ofera servicii altor obiecte, numite clienti, este descris de asa-numitul model client-server.

• Totalitatea serviciilor oferite de un obiect server constituie un contract sau o responsabilitate a obiectului fata de alte obiecte.

• Responsabilitatile sunt indeplinite prin intermediul unor operatii (alte denumiri folosite: metode, functii membru).

• Fiecare operatie a unui obiect se caracterizeaza printr-o semnatura unica, formata din: nume, o lista de parametri formali si un tip returnat.

• Multimea operatiilor unui obiect, impreuna cu regulile lor de apelare constituie protocolul obiectului.

3. Clase şi obiecte. Principiile lui Parnas. Încapsularea. Ierarhizarea. Membri statici. Clase şi obiecte Definitia 1 Clasa, intr-un anumit limbaj de programare, reprezinta definirea unui tip de obiecte abstracte sau concrete, adica descrierea proprietatilor, a datelor si a metodelor, a prelucrarilor, posibile asupra datelor. Clasa este, de fapt, o notiune abstracta, care defineste un anumit tip de obiecte, sau, altfel spus, o clasa reprezinta multimea posibila a mai multor obiecte de acelasi tip. Definitia 2 In primul rind un obiect reprezinta o entitate ( fizica, conceptuala sau soft). Definitie formala : Obiect este o instanta a unei clase, care utilizeaza atributele si implimenteaza metodele acesteia. Crearea unui obiect presupune specificarea clasei din care face parte, astfel identificandu-se proprietatile obiectului si modul in care acestea pot fi folosite si prelucrate.

Page 3: APPOO Teme Evaluare

3

Principiile lui Parnas. Principiile lui Parnas sunt:

1. Declararea (interfata) clasei trebuie sa asigure clientul doar cu informatia necesara pentru utilizarea eficienta a ei, dar nici o alta informatie in plus.

2. Metodele trebuie sa aiba acces doar la informatia necesara pentru indeplinirea responsabilitatilior lor. Încapsularea – numită și ascunderea de informații: Asigură faptul că obiectele nu pot schimba starea internă a altor obiecte în mod direct (ci doar prin metode puse la dispoziție de obiectul respectiv); doar metodele proprii ale obiectului pot accesa starea acestuia. Fiecare tip de obiect expune o interfață pentru celelalte obiecte care specifică modul cum acele obiecte pot interacționa cu el. Incapsularea serveste la separarea interfetei de implementarea acesteia. Avantaje:

• Ofera independenta implimentarii de interfata. • Previne coruperea datelor interne. • Permite mai multor echipe un lucru independent asupra modulelor. • Documentarea buna permite o buna mentenata, dar si o depanare buna.

Ierarhizarea

Adesea un grup de abstractiuni formeaza o ierarhie, iar prin identificarea acestor ierarhii, putem simplifica substantial intelegerea problemei. Ierarhizarea reprezinta o ordonare a abstractiunilor. Cele mai importante ierarhii in paradigma obiectuala sunt:

§ Ierarhia de clase (relatie de tip "is a") § Ierarhia de obiecte (relatie de tip "part of")

• Mostenirea (ierarhia de clase) Mostenirea defineste o relatie intre clase in care o clasa impartaseste structura si comportarea definita in una sau mai multe clase (dupa caz vorbim de mostenire simpla sau multipla). Asa cum aminteam mai sus, relatia de mostenire este cea care face diferenta intre programarea orientata pe obiecte si cea bazata pe obiecte. Semantic, mostenirea indica o relatie de tip "is a" ("este un/o"). De exemplu un urs "este un" mamifer si deci intre clasa ursilor si cea a mamiferelor exista o relatie de mostenire. Si in cazul programarii acesta este cel mai bun test pentru a detecta o relatie de mostenire intre doua clase A si B: A mosteneste pe B daca si numai daca putem spune ca "A este un fel de B". Daca A "nu este un" B atunci A nu ar trebui sa mosteneasca pe B. Prin urmare, mostenirea implica o ierarhie de tip generalizare/specializare, in care clasa derivata specializeaza structura si comportamentul mai general al clasei din care a fost derivata.

Agregarea(ierarhiadeobiecte)Agregareaesterelatiaintredouaobiecteincareunuldintreobiecteapartineceluilaltobiect.Agregarearedaapartentaunuiobiectlaunaltobiect.Semantic,agregareaindicaorelatiedetip"partof"("partedin").Deexempluintreoroatasiunautomobilexistaoastfelderelatie,intrucatputemspuneca"oroataesteopartedinautomobil".Membristatici.Membriistaticiexistainexemplareunicepentrufiecareclasa,findaccesatiincomundetoateinstanteleclaseirepective.Se recomanda ca referire unui membru static sa se faca prin intermediul numelui clasei si nu prin intermediul numelui obiect. Declararea unui membru static presupune precedarea acestuia de cuvantul cheie static: static tip_membru nume_membru_static; iar referirea unui membru static se face astfel: nume_clasa::nume_membru_static; unde, nume_membru_static poate fi o data sau o functie membru static. Membri static pot fii referiti fara a instantia clasa, ei nedepinzind de obiecte.

Page 4: APPOO Teme Evaluare

4

4. Ierarhii de clase și de obiecte. Modele de relații. Accesibilitatea membrilor in C++ şi Java. Ierarhizarea:

• ierarhii de clase(mostenirea) – mostenirea implica o ierarhie de tip generalizare sau specializare. • ierarhii de obiecte(agregare) – relatie dintre doua obiecte in care unul dintre obiecte apartine celuilalt

obiect. Modele de relatii:

• clasa are un caracter dual: ◦ ierarhie conceptuala ◦ ieragie de implementare

• obiectul corespunde unui tip:

◦ is-a ◦ has-a ◦ uses-a

Exemplu de relatii de obiecte: Accesibilitatea membrilor in C++. Specificatorii de acces definește drepturile de acces pentru atribute sau metode pe care-l urmează până la definirea unui alt specificator de acces sau până la sfârșitul unei clase. Cele trei tipuri de specificatori de acces sunt "private", "public", "protected". private: Membrii declarati ca "private", pot fi accesate numai în cadrul aceleiași clase, și nu din afara clasei. publica: Membrii declarat ca "public" sunt accesibile în cadrul clasei, cât și din afara ei. protected: Membrii declarat ca "protected" nu pot fi accesate din afara clasei, dar pot fi accesate de la o clasa mostenita. Aceasta este utilizată atunci când este aplicată mostenirea membrilor unei clase.

Accesibilitatea membrilor in java. In java sunt utilizate aceeasi specificatori ca si in C++ insa apare inca un specificator - “package-private(no modifier)”. package-private(no modifier) – daca un atribut utilizeaza acest specificator atunci el este public pentru tot pachetul insa private pentru accesarea innafara pachetului. 5. Ierarhii de clase și de obiecte. Funcţii virtuale. Moştenire multiplă. Blocarea moștenirii.

Page 5: APPOO Teme Evaluare

5

Ierarhii de clase si obiecte Despre aceasta intreabare a vorbit si Max Gribincea mai sus, eu vreau sa adaug doar doua propozitii despre care el probabil a vorbit, sau poate nu, insa acestea clarifica totul. (c stati, sper c in timpul examenului propozitia asta sa no copietz :D). Ierarhiile de clase reprezinta o multime de clase legate prin mostenire unde o clasa se caracterizeaza prin “este o”. Adica clasa B este un fel de Clasa A (B mostenind de la A). Ierarhiile de obiecte reprezinta o multime de obiecte legate prin compozitie si agregare, la nivel de clase caracterizate prin “contine un”. Adica clasa B contine un obiect de clasa A. Functii virtuale În programarea orientată pe obiecte (POO), o funcție virtuală sau metodă virtuală este o funcție al cărei comportament, în virtutea declarării acesteia ca fiind "virtuală", este determinat de către definiția unei funcții cu aceeași semnătură cea mai îndepărtată pe linia succesorală a obiectului în care este apelată. Acest concept este o foarte importantă parte din porțiunea de polimorfism a paradigmei de programare pe obiecte (POO). Exemplu functii virtuale C++: class Animal { public: virtual void eat() { cout << "Eu mănânc așa cum o poate face orice Animal.\n"; } }; class Wolf : public Animal { public: void eat() { cout << "Eu înfulec ca un lup!\n"; } }; class Fish : public Animal { public: void eat() { cout << "Eu mă hrănesc ca un pește!\n"; } }; class OtherAnimal : public Animal { }; int main() { Animal *anAnimal[4]; anAnimal[0] = new Animal(); anAnimal[1] = new Wolf(); anAnimal[2] = new Fish(); anAnimal[3] = new OtherAnimal(); for(int i = 0; i < 4; i++) anAnimal[i]->eat(); } Rezultatul C++: Eu mănânc așa cum o poate face orice Animal. Eu înfulec ca un lup! Eu mă hrănesc ca un pește! Eu mănânc așa cum o poate face orice Animal. Exemplu functii viruale C#:

Page 6: APPOO Teme Evaluare

6

class A { public void F() { Console.WriteLine("A.F"); } public virtual void G() { Console.WriteLine("A.G"); } } class B: A { new public void F() { Console.WriteLine("B.F"); } public override void G() { Console.WriteLine("B.G"); } } class Test { static void Main() { B b = new B(); A a = b; a.F(); b.F(); a.G(); b.G(); } } Rezultate C#: A.F B.F B.G B.G Java functii virtuale: In Java toate metodele non-statice sunt implicit virtuale. Doar cele cu cuvintul cheie final, si cele private nu sunt virtuale. Exemplu functii virt Java: (acesta merge si la polimorfism ca si cele C++ si C# de mai sus) class Vehicle{ public void move(){ System.out.println(“Vehicles can move!!”); } } class MotorBike extends Vehicle{ public void move(){ System.out.println(“MotorBike can move and accelerate too!!”); } } class Test{ public static void main(String[] args){ Vehicle vh=new MotorBike(); vh.move(); // prints MotorBike can move and accelerate too!! vh=new Vehicle(); vh.move(); // prints Vehicles can move!! } } Mostenirea multipla

Page 7: APPOO Teme Evaluare

7

Mostenirea multipla este mecanismul prin care o clasă preia structura (datele membru) şi comportamentul (metodele) a doua sau mai multe clase la care adaugă elemente specifice. Moştenire multiplă - clasa derivată preia caracteristicile şi metodele de la mai multe clase de bază. Mostenirea multipla este prezenta in limbajul C++ si nu este implementata in C# sau Java (cu toate ca exista metode de utilizare a interfetelor pentru a realiza ceva de genul mostenirii multiple). Exemplu mostenire multipla C++: class Imprimanta{ protected: int rezolutie; public: Imprimanta(int rezolutie=600){ this->rezolutie = rezolutie; cout<<"Apel Constr. Imprimanta\n"; } ~Imprimanta(){ cout<<"Apel Destr. Imprimanta\n"; } void print(char *text){ cout<<"Print "<<text<<"\n"; } }; class Scaner{ protected: int rezolutie; public: Scaner(int rezolutie=1200){ this->rezolutie = rezolutie; cout<<"Apel Constr. Scaner\n"; } ~Scaner(){ cout<<"Apel Destr. Scaner\n"; } void scan(){ cout<<"Scanez\n"; } }; class MultiFunctionala: public Imprimanta, public Scaner{ public: MultiFunctionala(int rezI, int rezS): Imprimanta(rezI), Scaner(rezS) { cout<<"Apel Constr. MultiFunctionala\n"; } ~MultiFunctionala(){ cout<<"Apel Destr. MultiFunctionala\n"; } }; void main(){ MultiFunctionala m(300,600); m.print("hello"); m.scan(); } Rezultatul programului de mai sus: Apel Constr. Imprimanta Apel Constr. Scaner Apel Constr. MultiFunctionala Print hello Scanez Apel Destr. MultiFunctionala Apel Destr. Scaner Apel Destr. Imprimanta Blocarea mostenirii

Page 8: APPOO Teme Evaluare

8

Exista posibilitatea de a bloca extinderea unei clase, sa nu mai transfere proprietatile si metodele ei vreunei sub-clase legata de ea. Pentru aceasta se adauga termenul final inaintea cuvantului class Exemplu blocarea mostenirii C++: class MakeFinal { private: ~MakeFinal() { }; friend class FinalClass; }; class FinalClass : virtual public MakeFinal // <-- virtual is the key { public: FinalClass() { cout << "FinalClass::ctor" << endl;} ~FinalClass() { cout << "FinalClass::dtor" << endl;} }; class NotPossible : public FinalClass { public: NotPossible() { cout << "NotPossible::ctor" << endl;} ~NotPossible() { cout << "NotPossible::~ctor" << endl;} }; Exemplu blocarea mostenirii C#: sealed class SealedClass { public int x; public int y; } //class MyDerivedC: SealedClass {} // Error class SealedTest2 { static void Main() { SealedClass sc = new SealedClass(); sc.x = 110; sc.y = 150; Console.WriteLine("x = {0}, y = {1}", sc.x, sc.y); } } // Output: x = 110, y = 150

Exemplu blocarea mostenirii Java: class Point { int x, y; } class ColoredPoint extends Point { int color; } // Colored3dPoint class cannot be extended further // clasa Colored3dpoint nu poate fi mostenita final class Colored3dPoint extends ColoredPoint { int z; }

6. Polimorfism

Page 9: APPOO Teme Evaluare

9

Polimorfismul este exemplul cel mai practic al reutilizării, el fiind prin definiţie capacitatea unei entităţi de a lua mai multe forme. Funcţiile se diferenţiază prin:

· numele funcţiei; · lista de parametri; · valoarea returnată,

aceste forme de diferenţiere putând exista fie simultan, fie separat. Polimorfismul este universal sau ad-hoc. Polimorfismul universal la rândul său se împarte în polimorfism parametric şi polimorfism incluziune.

Polimorfismul parametric presupune că diferenţa între funcţii se realizează prin lista de parametri şi/sau valoarea returnată, funcţiile având acelaşi nume. El se referă la posibilitatea utilizării unei singure funcţii (cod, nume, funcţionalitate) asupra unui set de tipuri, dacă un argument al semnăturii sale determină tipul corespunzător fiecărui apel al funcţiei.

Polimorfismul incluziune presupune manipularea obiectelor de un anumit tip în situaţii în care se cer tipuri diferite de tipul obiectelor. Astfel obiectele de tip ClasaDerivata pot fi utilizate în orice situaţie care necesită prezenţa unor obiecte de tipul ClasaDeBaza, unde ClasaDeBaza este o superclasă a clasei ClasaDerivata. Polimorfismul incluziune permite unei funcţii să opereze asupra unui set de tipuri determinate de relaţii de subtip (ierarhii de clase). Implementarea unei asemenea forme de polimorfism permite folosirea unor tehnici care să trateze un obiect ca instanţă a mai multor clase în acelaşi timp (între care există relaţii de superclasa-subclasă). În acest fel organizarea şi prelucrarea colecţiilor de obiecte eterogene se face într-o manieră flexibilă şi elegantă.

Polimorfismul ad-hoc la rândul său se împarte în polimorfism coerciziune şi polimorfism supraîncărcare.

Polimorfismul coerciziune este caracteristic limbajelor de programare care dispun de facilităţi de

conversie internă între tipuri. Polimorfismul supraîncărcare se obţine prin supraîncărcarea funcţiilor şi mascarea lor în cadrul unei ierarhii de clase. Atfel, operaţiile polimorfice sunt operaţii cu acelaşi nume dar cu implementări diferite. De exemplu, de-a lungul unei ierarhii de clase, o operaţie definită într-o superclasă poate fi redefinită într-o subclasă. Astfel ea este polimorfică, decizia de selecţie a funcţiei active luându-se în funcţie de parametri de apel.

Specifice limbajului C++ sunt polimorfismul ad-hoc şi polimorfismul de incluziune, acesta din urmă realizându-se prin intermediul funcţiilor virtuale şi a legării dinamice.

Avantajele sistemelor polimorfice sunt partajabilitatea comportării, posibilitatea de definire a operaţiilor abstracte asociate tipurilor, flexibilitate.

Page 10: APPOO Teme Evaluare

10

Polimorfismul supraîncărcare void display() const{ cout<<"no arguments"; } void display(int a) const{ cout<<"display("<<a<<")"; } int main() { display(); display(10); return 0; } Polimorfismul coerciziune void display( int a) const{ cout<<"display("<<a<<")"; } int main() { display(10); display(12,6); display('\n'); return 0; } Polimorfismul incluziune using namespace std; class A { public: virtual void say() { cout<<"silence..."; } virtual ~A(); }; class B:public A { public: virtual ~B(); virtual void say() { cout<<"B say...."; } }; class C:public A { public: virtual ~C(); virtual void say() { cout<<"C say ...."; } }; void main() {

A*arrayofas[2]; arrayofas[0]=new B(); arrayofas[1]= new C(); for( int i=0;i<1;++i) { arrayofas[i]->say(); } } Polimorfismul parametric C++ template<class T,int lenght> class typeblock { public: typeblock() { p=new T[lenght]; } ~typeblock() { delete[] p; } operator T*() { return p; } protected: T*p; }; main { typeblock <char ,256> char block; typeblock<int ,1024> int block; } Java public class entry<K,V> { private final K key; private final V value; public entry (K k,V v) { key=k; value=v; } public k getkey() { return key; } public v getvalue() { return value;} public stringtostring() { return "("+ key+...")";

Page 11: APPOO Teme Evaluare

11

Determinarea şi Analiza Cerinţelor. Înainte de a proiecta arhitectura unui sistem software este important să se obțină o imagine clară asupra cerințelor care influențează arhitectura. De obicei aceste cerințe sunt cerințe non-funcționale care se referă la calitatea sistemului software. Procesul de identificare a cerințelor care afectează arhitectura are două tipuri de intrări: pe de o parte arhitectul trebuie să analizeze cerințele funcționale, iar pe de altă parte el trebuie să țină cont și de cerințele venite din partea celor care vor interacționa cu aplicația. În urma analizei efectuate asupra celor două tipuri de cerințe rezultă cerințele care influențează arhitectura sistemului software. Procesul de analiză a cerințelor în vederea izolării cerințelor care influențează arhitectura este ilustrat in Fig. 11.2.

Unele cerințe vor acționa ca și constrângeri ele limitând opțiunile arhitectului. În Tabela 11.1 sunt prezentate exemple de cerințe care influențează arhitectura, iar în Tabela 11.2 sunt prezentate exemple de cerințe care impun constrângeri.

Un alt aspect care trebuie avut în vedere vis-a-vis de cerințele care influențează arhitectura unui sistem software, este faptul că aceste cerințe nu sunt egale, unele fiind mai importante decât altele. De aceea este necesară o prioritizare a acestor cerințe. De obicei se folosesc trei niveluri de prioritizare: - Ridicată – sistemul software trebuie să implementeze cerințele cu această prioritate. Aceste cerințe au un cuvânt greu de spus în ceea ce privește arhitectura. - Medie – cerințele cu această prioritate vor trebuii implementate la un moment dat, dar nu sunt absolut necesare pentru prima versiune. - Scăzută– funcționalități dorite, dar care se pot implementa în măsura posibilităților. Prioritizarea cerințelor se complică atunci când apar conflicte între cerințe, de ex.: timp scurt până la scoaterea pe piață a produsului vs. dezvoltarea de componente generice și reutilizabile. De cele mai multe ori rezolvarea acestor conflicte nu este ușoară, dar este sarcina arhitectului să le rezolve.

Page 12: APPOO Teme Evaluare

12

Etapa de Proiectare. Arhitecturi. Reprezintă cea mai importantă acțiune întreprinsă de către arhitect. Un document de cerințe foarte bine structurate, respectiv o comunicare bună cu restul echipelor implicate în proiect nu însemnă nimic dacă se proiectează o arhitectură slabă. Etapa de proiectare a arhitecturii are ca și intrări cerințele obținute în etapa anterioară iar ca rezultat se obține un document care descrie arhitectura sistemului software. Proiectarea arhitecturii se realizează în doi pași: primul pas se referă la alegerea unei strategii globale, iar al doilea constă din specificarea componentelor individuale și a rolului pe care fiecare componentă îl joacă în arhitectura globală. Validarea Arhitecturii Scopul etapei de validare este acela de a verifica faptul că arhitectura proiectată este potrivită pentru sistemul software care urmează să fie dezvoltat. Principala dificultate în ceea ce privește validarea unei arhitecturi constă în faptul că în acest moment nu există un produs software “fizic” care să poată fi executat și testat. Există două metode prin care se poate valida arhitectura unui sistem software: testarea manuală utilizând scenarii, respectiv validare prin construirea unui prototip. Utilizarea Scenariilor Utilizarea scenariilor pentru validarea arhitecturii unui sistem software presupune definirea unor stimuli care să aibă efect asupra arhitecturii. După care se face o analiză pentru a se determina care va fi răspunsul arhitecturii la un astfel de scenariu. Dacă răspunsul este cel dorit atunci se consideră că scenariul este satisfăcut de arhitectură. Dacă răspunsul nu este cel dorit sau este greu de calificat atunci s-a descoperit o zonă de risc în arhitectură. Se pot imagina scenarii care să evalueze oricare din cerințele sistemului. Crearea Unui Prototip Deși scenariile sunt tehnici foarte utile în vederea testării unei arhitecturi, nu întotdeauna verificarea unui scenariu se poate face doar prin analiza arhitecturii, de aceea în anumite situații se recurge la construirea unui prototip care să permită verificarea anumitor scenarii. Un prototip se poate construi din două motive: - Proof-of-concept: verifică dacă se poate implementa arhitectura proiectată astfel încât să satisfacă cerințele. - Proof-of-technology: verifică faptul că tehnologia middleware selectată se comportă așa cum se așteaptă. Odată ce prototipul a fost implementat și testat răspunsul arhitecturii la stimulii prevăzuți în scenarii se poate obține cu un înalt grad de certitudine. Deși un prototip poate fi foarte util în ceea ce privește validarea unei arhitecturi, trebuie avut grijă ca dezvoltarea unui astfel de prototip să nu dureze prea mult. De obicei un prototip este abandonat după ce arhitectura a fost validată, de aceea dezvoltarea unui prototip nu trebuie să dureze mai mult de câteva zile, cel mult 1-2 săptămâni.

Page 13: APPOO Teme Evaluare

13

1 2 3 4 5

publicclassMain{ privateEventsHandlerevHandler; privateMonitormonitor; privateCommandsHandlercmdHandler; }

1 2 3 4 5 6 7

public class CommandsHandler { private Monitor mon; public void configureParameter () { } public short[] getParams (byte[] types) { return null; } }

1 2 3 4

public class EventsHandler { public void send (Report r) { } }

1 2 3 4 5 6 7 8 9

10 11 12 13 14 15 16

public class Monitor { private byte[] monitoredTypes; private short measuringPeriod; private Timer timers; private Parameter params; private MeasuringTool tool; private MeasuringAPI api; private boolean toolOrAPI; public Monitor () { } public void run () { } public void addParam () { } public short getValue (byte type) { return 0;

Page 14: APPOO Teme Evaluare

14

17 18

} }

1 2 3 4 5 6 7 8 9

10 11 12 13 14 15 16 17 18

public class Parameter { private short value; private short aboveThr; private short belowThr; private byte type; private Report rep; private EventsHandler reportHandler; public Parameter () { } public void setAboveThr (short val) { } public void setBelowThr (short val) { } public void setValue (short val) { } public void periodicReport () { } public void checkThresholds () { } public byte getType () { return 0; } public short getValue () { return 0; } }

1 2 3 4 5

public class MeasuringAPI extends Measuring { public short[] measure (byte[] types) { return null; } }

1 2 3 4 5

public class MeasuringTool extends Measuring { public short[] measure (byte[] types) { return null; } }

1 2 3

public class Measuring { public Measuring () { } }

1 2 3 4 5 6 7 8 9

10 11 12 13 14 15

public class Report { private byte type; private byte reason; private short value; public Report () { } public byte getReason () { return 0; } public byte getType () { return 0; } public short getValue () { return 0; } }

1 2 3 4

public class Timer { private short interval; private Parameter param; public Timer () { }

Page 15: APPOO Teme Evaluare

15

5 6

public void run () { } }