Professional Documents
Culture Documents
Mesaje i responsabiliti
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 comuniti orientat-obiect comunica intre ei .
Urmtorul principiu important explic utilizarea de mesaje pentru a iniia o aciune:
Aciune este iniiat n programarea orientat pe obiecte prin transmiterea unui mesaj de la un agent
(un obiect), responsabil pentru aciunile. Mesajul codific cererea de aciune i este nsoit de orice
informaii suplimentare (argumente / parametri) necesare pentru ndeplinirea cererii.
Receptorul este obiectul la care este trimis mesajul. Dac receptorul accept mesajul, accept
responsabilitatea de a efectua aciunea indicat. Ca rspuns 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 gsi pe altcineva pentru a face munca
de exemplu reutilizarea componentelor care ar fi putut fi scrise de altcineva.
interpretarea mesajului este determinat de ctre receptor i poate varia n funcie de diferite
receptoare. De exemplu, dac te-a trimis mesajul "flori livrare" la un prieten, ea, probabil, va fi
neles 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 responsabiliti.
cererile Clientului indic doar rezultatul dorit. Receptoarele sunt liberi s urmreasc orice tehnica
care atinge rezultatele dorite
gndire n acest fel permite o mai mare independen ntre obiecte.
Astfel, obiectele au responsabiliti pe care sunt dispui s-i ndeplineasc, la cerere. Colectarea de
responsabiliti asociate cu un obiect este adesea numit protocol
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.
3
is-a
has-a
uses-a
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
6
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.
Motenire 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();
}
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
6. Polimorfism
8
Polimorfismul este exemplul cel mai practic al reutilizrii, el fiind prin definiie capacitatea unei
entiti de a lua mai multe forme.
Funciile se difereniaz prin:
numele funciei;
lista de parametri;
valoarea returnat,
aceste forme de difereniere putnd exista fie simultan, fie separat.
Polimorfismul este universal sau ad-hoc.
Polimorfismul universal la rndul su se mparte n polimorfism parametric i polimorfism incluziune.
Polimorfismul parametric presupune c diferena ntre funcii se realizeaz prin lista de parametri
i/sau valoarea returnat, funciile avnd acelai nume. El se refer la posibilitatea utilizrii unei singure
funcii (cod, nume, funcionalitate) asupra unui set de tipuri, dac un argument al semnturii sale determin
tipul corespunztor fiecrui apel al funciei.
Polimorfismul incluziune presupune manipularea obiectelor de un anumit tip n situaii n care se cer
tipuri diferite de tipul obiectelor. Astfel obiectele de tip ClasaDerivata pot fi utilizate n orice situaie care
necesit prezena unor obiecte de tipul ClasaDeBaza, unde ClasaDeBaza este o superclas a
clasei ClasaDerivata. Polimorfismul incluziune permite unei funcii s opereze asupra unui set de tipuri
determinate de relaii 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 acelai timp (ntre
care exist relaii de superclasa-subclas). n acest fel organizarea i prelucrarea coleciilor de obiecte
eterogene se face ntr-o manier flexibil i elegant.
Polimorfismul ad-hoc la rndul su se mparte n polimorfism coerciziune i polimorfism
suprancrcare.
Polimorfismul coerciziune este caracteristic limbajelor de programare care dispun de faciliti de
conversie intern ntre tipuri.
Polimorfismul suprancrcare se obine prin suprancrcarea funciilor i mascarea lor n cadrul unei
ierarhii de clase. Atfel, operaiile polimorfice sunt operaii cu acelai nume dar cu implementri diferite. De
exemplu, de-a lungul unei ierarhii de clase, o operaie definit ntr-o superclas poate fi redefinit ntr-o
subclas. Astfel ea este polimorfic, decizia de selecie a funciei active lundu-se n funcie de parametri de
apel.
Specifice limbajului C++ sunt polimorfismul ad-hoc i polimorfismul de incluziune, acesta din urm
realizndu-se prin intermediul funciilor virtuale i a legrii dinamice.
Avantajele sistemelor polimorfice sunt partajabilitatea comportrii, posibilitatea de definire a
operaiilor abstracte asociate tipurilor, flexibilitate.
Polimorfismul suprancrcare
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+...")";
10
nainte de a proiecta arhitectura unui sistem software este important s se obin o imagine clar asupra
cerinelor care influeneaz arhitectura. De obicei aceste cerine sunt cerine non-funcionale care se refer la
calitatea sistemului software.
Procesul de identificare a cerinelor care afecteaz arhitectura are dou tipuri de intrri: pe de o parte
arhitectul trebuie s analizeze cerinele funcionale, iar pe de alt parte el trebuie s in cont i de cerinele
venite din partea celor care vor interaciona cu aplicaia. n urma analizei efectuate asupra celor dou tipuri
de cerine rezult cerinele care influeneaz arhitectura sistemului software. Procesul de analiz a cerinelor
n vederea izolrii cerinelor care influeneaz arhitectura este ilustrat in Fig. 11.2.
Unele cerine vor aciona ca i constrngeri ele limitnd opiunile arhitectului. n Tabela 11.1 sunt prezentate
exemple de cerine care influeneaz arhitectura, iar n Tabela 11.2 sunt prezentate exemple de cerine care
impun constrngeri.
Un alt aspect care trebuie avut n vedere vis-a-vis de cerinele care influeneaz arhitectura unui sistem
software, este faptul c aceste cerine nu sunt egale, unele fiind mai importante dect altele. De aceea este
necesar o prioritizare a acestor cerine. De obicei se folosesc trei niveluri de prioritizare:
- Ridicat sistemul software trebuie s implementeze cerinele cu aceast prioritate. Aceste cerine au un
cuvnt greu de spus n ceea ce privete arhitectura.
- Medie cerinele cu aceast prioritate vor trebuii implementate la un moment dat, dar nu sunt absolut
necesare pentru prima versiune.
- Sczut funcionaliti dorite, dar care se pot implementa n msura posibilitilor.
Prioritizarea cerinelor se complic atunci cnd apar conflicte ntre cerine, de ex.: timp scurt pn la
scoaterea pe pia a produsului vs. dezvoltarea de componente generice i reutilizabile. De cele mai multe
ori rezolvarea acestor conflicte nu este uoar, dar este sarcina arhitectului s le rezolve.
11
Reprezint cea mai important aciune ntreprins de ctre arhitect. Un document de cerine 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 intrri cerinele obinute n etapa
anterioar iar ca rezultat se obine un document care descrie arhitectura sistemului software. Proiectarea
arhitecturii se realizeaz n doi pai: 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 privete 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
utiliznd 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 rspunsul
arhitecturii la un astfel de scenariu. Dac rspunsul este cel dorit atunci se consider c scenariul este
satisfcut de arhitectur. Dac rspunsul 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 cerinele sistemului.
Crearea Unui Prototip
Dei scenariile sunt tehnici foarte utile n vederea testrii unei arhitecturi, nu ntotdeauna verificarea unui
scenariu se poate face doar prin analiza arhitecturii, de aceea n anumite situaii 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 nct s satisfac
cerinele.
- Proof-of-technology: verific faptul c tehnologia middleware selectat se comport aa cum se ateapt.
Odat ce prototipul a fost implementat i testat rspunsul arhitecturii la stimulii prevzui n scenarii se poate
obine cu un nalt grad de certitudine.
Dei un prototip poate fi foarte util n ceea ce privete 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 cteva zile,
cel mult 1-2 sptmni.
12
1
2
3
4
5
1
2
3
4
5
6
7
1
2
3
4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
}
18 }
1 public class Parameter {
private short value;
2
private short aboveThr;
3
private short belowThr;
4
private byte type;
5
private Report rep;
6
private EventsHandler reportHandler;
7
public Parameter () { }
8
public void setAboveThr (short val) { }
9
public void setBelowThr (short val) {
}
10
public
void
setValue
(short
val)
{
}
11
public void periodicReport () {
}
12
public void checkThresholds () {
}
13
public
byte
getType
()
{
14
return 0;
}
15
public
short
getValue
() {
16
return 0;
17
}
}
18
1
2
3
4
5
1
2
3
4
5
1
2
3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1
2
3
4
5
6 }
15