2. Concepte de proiectare software şi arhitectură
1. Conceptul orientat pe obiecte (object oriented)
Ascunderea informaţiei datează din 1972(Parnas) - module, modificările aveau impact mic sau deloc asupra celorlalte module.
Conceptul de clase şi moştenire, folosit prima dată în Simula 67 (Dahl and Hoare în 1972), dar ajunge să fie răspândit şi acceptat pe larg odată cu SmallTalk în 1983 (Goldberg şi Hobson).
Obiect - o entitate din lumea reală, fizică sau conceptuală, care dă o înţelegere a lumii reale şi aşadar formează o bază pentru o soluţie software. Exemple de obiecte fizice: uşă, motor, lampă; obiecte conceptuale: cont, tranzacţie.
Obiectul împachetează atât datele cât şi procedurile, numite operaţii sau metode. Noi le vom spune operaţii.
Semnătura unei operaţii specifică numele operaţiei, parametrii operaţiei şi valoarea returnată.
Interfaţa obiectului - setul de operaţii furnizate de obiect.
Notiuni legate de clase şi obiecte
Atribute şi operaţii ...
2. Ascunderea informaţiei
Necesitate: sistemele timpurii erau vulnerabile la defecte şi dificil de modificat pentru că făceau acces la date globale. Parnas (1972) a arătat că prin eliminarea datelor globale programele devin mult mai uşor modificabile. Ascunderea informaţiei - folosită la descompunerea sistemelor în module. Fiecare modul poate ascunde o decizie de proiectare.
Folosind proiectarea OO ascunderea informaţiei se face prin implementarea obiectului, spre exterior sunt vizibile doar metodele. Schimbările de implementare rămân invizibile pentru utilizator (încapsulare).
Exemple de ascundere a informaţiei:
a) ascunderea structurilor de date interne
o problemă importantă în proiectare: o structură importantă de date, ce e accesată de mai multe obiecte, poate sa trebuiască să fie modificată. Fără ascunderea informaţiei, fiecare schimbare în structură necesită schimbări în obiectele care o accesează. Soluţia e ascunderea informaţiilor de implementare, încapsularea lor şi asigurarea accesului doar prin metode. Această formă de ascundere a informaţiei se numeşte data abstraction.
Ca exemplu: o stivă. În varianta tradiţională, stiva e structură globală, deci fiecare modul accesează stiva direct:
În varianta cu ascunderea informaţiei se ascunde implementarea stivei de module. Ele vor avea acces prin metode (push, pop, empty, full).
Datorită ascunderii implementării, daca se trece la implementarea cu liste în loc de tablou, modulele nu vor fi afectate:
b) ascunderea informaţiei aplicată la interfaţarea unui dispozitiv I/O
pentru a putea înlocui un dispozitiv fără a modifica modulul software care îl foloseşte, soluţia este o interfaţă virtuală la dispozitiv care ascunde detaliile specifice dispozitivului.
3. Moştenire
E un mecanism de abstracţie util în analiza şi proiectarea software. Prin moştenire se modelează în mod natural obiecte din altele similare, dar faţă de care au cel puţin o deosebire. De exemplu, câinii şi pisicile moştenesc caracteristicile mamiferelor, dar latră/miaună.
Moştenirea este un mecanism de partajare şi reutilizare a codului între clase. Clasa fiu moşteneşte proprietăţile clasei părinte. Apoi ea poate adapta structura datelor sau metodelor. Clasa părinte - superclasă sau clasă de bază. Clasa fiu – subclasă sau clasă derivată.
Adaptarea clasei părinte pentru a forma clasa fiu se numeşte specializare. Clasele fiu pot fi specializate în continuare, permiţând crearea de ierarhii de clase, numite ierarhii de generalizare/specializare.
4. Obiecte active şi pasive
Obiect pasiv - aşteaptă un mesaj pentru a invoca o operaţie şi nu iniţiază niciodată acţiuni.
ADA şi Java suportă obiecte active, care se execută independent de alte obiecte active.
Obiecte active - sunt taskuri concurente, fiecare cu firul său de control propriu (viaţă proprie), care pot iniţia acţiuni cu impact asupra altor obiecte.
Obiectele pasive pot invoca operaţii din alte obiecte pasive. Operaţiile obiectelor pasive pot fi apelate de obiectele active. Comunicarea între obiecte se realizează prin mesaje. Forma strâns cuplată a mesajelor este apelul de procedură. În Java un obiect poate încapsula un fir de control, dar să aibă şi metode apelabile de către alte obiecte, deci are caracter activ – inactiv(pasiv).
5. Procesarea concurentă
În general, când rulează mai multe taskuri, ele se execută secvenţial. Concurenţa se obţine prin executarea lor în paralel. Dijkstra 1968, Hoare 1974
Avantaje:
a) model natural de proiectare, reflectă paralelismul natural din domeniul problemei;
b) se separă ce face fiecare task de când face; sistemele devin mai uşor de înţeles;
c) reducerea timpului de execuţie; o creştere a performanţelor prin realizarea operaţiilor de I/O în paralel cu calculele. La mai multe procesoare performanţele cresc prin executarea fiecărui task pe alt procesor.
d) Permite posibilităţi de programare (planificare) mai bune, taskurile critice în timp pot primi o prioritate mai mare.
e) Pot permite o analiză de performanţă timpurie.
procese uşoare - un singur fir de control, procese tradiţionale, o unitate de alocare a resurselor pentru procesor şi memorie
procese grele - are mai multe fire de control, permite concurenţă internă.
6. Cooperarea între taskuri concurente
În proiectarea sistemelor concurente există mai multe situaţii ce trebuiesc evitate. Când taskurile cooperează apar trei probleme:
a) Problema excluderii mutuale - se produce când taskurile au nevoie de acces exclusiv la resurse, ca date comune sau periferice. O variantă a acestei probleme e problema mai multor scriitori şi cititori.
b) Problema sincronizării taskurilor – sincronizarea operaţiilor taskurilor ce rulează concurent.
c) Problema producător/consumator.
a) excluderea mutuală - exemplu:
scrierea la imprimantă a două taskuri
soluţia - semafor cu două operaţii: aquire(semafor), release(semafor)
secţiunea (regiunea) critică - zonă cu acces exclusiv
ex:
aquire(sensor semafor)
access sensor [secţiune critică]
release (sensor semafor).
b) sincronizarea taskurilor
când două taskuri trebuie să-şi sincronizeze operaţiile, fără comunicare de date între ele
În UML cele două taskuri se reprezintă ca obiecte active cu un semnal eveniment asincron trimis de emiţător(task) la receptor. Emiţătorul execută o operaţie signal(event), iar destinaţia o operaţie wait(event), care îl suspendă până la apariţia semnalului.
Ex: sistem concurent cu doi roboţi: un robot de poziţionare şi unul de găurire
c) problema producător/consumator
un task care produce date, altul care le preia. La sistemele secvenţiale se transmit date la proceduri, dar se transmite şi controlul. În sistemele concurente, fiecare task are propriul fir de control şi taskurile se execută asincron. De aceea e nevoie ca taskurile să se sincronizeze pentru a schimba date.
Producătorul trebuie să producă datele înainte ca consumatorul să aibă nevoie de ele. Dacă consumatorul este gata să preia datele, dar ele nu au fost produse, va trebui să aştepte. Dacă producătorul are datele, dar consumatorul nu e gata să le recepţioneze, va trebui să aştepte, sau să pună datele într-un buffer.
Soluţia e comunicarea.