Sunteți pe pagina 1din 15

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.

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.

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
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 (ierarhia de obiecte)
Agregarea este relatia intre doua obiecte in care unul dintre obiecte apartine celuilalt obiect. Agregarea reda
apartenta unui obiect la un alt obiect. Semantic, agregarea indica o relatie de tip "part of" ("parte din"). D e exemplu
intre o roata si un automobil exista o astfel de relatie, intrucat putem spune ca "o roata este o parte din automobil".

Membri statici. Membrii statici exista in exemplare unice pentru fiecare clasa, find accesati in comun de toate instantele clasei repective.

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.

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

corespunde unui tip: ◦ is - a ◦ has-a ◦ uses-a Exemplu de relatii de obiecte:

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.

când este aplicat ă mostenirea membrilor unei clase. Accesibilitatea membrilor in java. In java sunt utilizate

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.

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#:

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();

vh=new Vehicle();

vh.move();

// prints MotorBike can move and accelerate too!!

// prints Vehicles can move!!

Mostenirea multipla

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

{

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

{

public:

// <-- virtual is the key

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

Exemplu blocarea mostenirii Java:

{

class Point

 

public int x; public int y;

{

int x, y;

}

}

//class MyDerivedC: SealedClass {} // Error

class ColoredPoint extends Point

 

{

class SealedTest2

int color;

{

}

static void Main()

{

// Colored3dPoint class cannot be extended

final class Colored3dPoint extends ColoredPoint

SealedClass sc = new SealedClass(); sc.x = 110; sc.y = 150; Console.WriteLine("x = {0}, y = {1}",

further // clasa Colored3dpoint nu poate fi mostenita

sc.x, sc.y);

{

}

int z;

}

}

// Output: x = 110, y = 150

6.

Polimorfism

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.

Polimorfismul supraîncă rcare void display() const{ cout<<"no arguments";

}

A*arrayofas[2];

arrayofas[0]=new B();

arrayofas[1]= new C(); for( int i=0;i<1;++i)

void display(int a) const{ cout<<"display("<<a<<")";

{

arrayofas[i]->say();

}

}

int main()

}

{ display();

 

Polimorfismul parametric C++

 

display(10);

template<class T,int lenght>

return 0;

}

class typeblock

Polimorfismul coerciziune

{

void display( int a) const{

public:

cout<<"display("<<a<<")";

typeblock()

}

{

int main()

 

p=new T[lenght];

{

display(10);

 

}

display(12,6);

~typeblock()

display('\n');

{

return 0;

delete[] p;

}

}

Polimorfismul incluziune

operator T*()

{

using namespace std; class A

 

}

return p;

{

protected:

 

public:

T*p;

virtual void say()

 

};

{

main

cout<<"silence

";

{

}

typeblock <char ,256> char block;

virtual ~A();

 

typeblock<int ,1024> int block;

};

}

class B:public A

Java

{

public class entry<K,V>

 

public:

{

virtual ~B(); virtual void say()

 

private final K key; private final V value;

{

public entry (K k,V v)

cout<<"B say

";

{

}

key=k;

};

value=v;

class C:public A

 

}

{

public k getkey()

 

public:

{

virtual ~C();

 

return key;

virtual void say()

}

{

public v getvalue()

cout<<"C say

";

{

}

return value;}

};

public stringtostring()

void main()

 

{

{

return "("+ key+

")";

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.

influen ț eaz ă arhitectura este ilustrat in Fig. 11.2. Unele cerin ț e vor ac

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.

prezentate exemple de cerin ț e care impun constrângeri. Un alt aspect care trebuie avut în

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.

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.

1 public class Main { 2   private EventsHandler evHandler ;   3 private Monitor

1

public class

Main

{

2

 

private EventsHandler evHandler ;

 

3

private Monitor monitor ;

 

4

private CommandsHandler cmdHandler ;

 

5

}

1

public class

CommandsHandler

{

2

 

private Monitor mon;

 

3

public void configureParameter () {

}

4

public short[] getParams (byte[] types) {

5

 

return null;

 

6

 

}

7

}

1

public class

EventsHandler

{

2

 

public void send (Report r) {

3

}

4

}

1

public class Monitor

 

{

2

 

private byte[] monitoredTypes;

3

private short measuringPeriod;

4

private Timer timers;

 

5

private Parameter params;

 

6

private MeasuringTool tool;

7

private MeasuringAPI api;

8

private boolean toolOrAPI;

9

public Monitor () {

 

10

}

11

public void run () {

 

12

}

13

public void addParam () {

 

14

}

15

public short getValue (byte type) {

16

 

return 0;

 
17 } 18 } 1 public class Parameter { 2 private short value; 3 private
17
}
18
}
1
public class
Parameter
{
2
private short value;
3
private short aboveThr;
4
private short belowThr;
5
private byte type;
6
private Report rep;
7
private EventsHandler reportHandler;
8
public Parameter () { }
9
public void setAboveThr (short val) { }
10
public void setBelowThr (short val) {
}
11
public void setValue (short val) {
}
12
public void periodicReport () {
}
13
public void checkThresholds () {
}
14
public byte getType () {
15
return 0;
}
16
public short getValue () {
17
return 0;
18
}
}
1
public class MeasuringAPI
extends Measuring
{
2
public short[] measure (byte[] types) {
3
return null;
4
}
5
}
1
public class MeasuringTool
extends Measuring
{
2
public short[] measure (byte[] types) {
3
return null;
4
}
5
}
1
public class Measuring
{
2
public Measuring () {
3
}
}
1
public class
Report
{
2
private byte type;
3
private byte reason;
4
private short value;
5
public Report () {
}
6
public byte getReason () {
7
return 0;
8
}
9
public byte getType () {
10
return 0;
11
}
12
public short getValue () {
13
return 0;
14
}
15
}
1
public class
Timer
{
2
private short interval;
3
private Parameter param;
4
public Timer () {
}

5

 

public void run () {

}

6

}