Advertisement
PopaLepo

TP

Jun 9th, 2020
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.02 KB | None | 0 0
  1. TP Curs 1
  2.  
  3. Problema - descompunere / constructie
  4. Domeniul problemei contine procese / date, domeniul solutiei contine un model (cu algoritmi si programe)
  5. Procesul de trecere de la domeniul problemei la domeniul solutiei se cheama procesul de abstractie
  6. Compararea rezultatelor observabile din domeniul problemei cu cele obtine in domeniul solutiei imbunatatesc procesul de abstractie.
  7.  
  8. proces de dezvoltare software, numit si ciclu de viata, contine
  9. input : cerintele de sistem
  10. output : un produs realizat
  11. Tehnologii de asistență software asistate de calculator (CASE).Ele sunt instrumente care oferă asistență automată pentru dezvoltarea de software. Scopul introducerii instrumentelor CASE este reducerea timpului și a costurilor de dezvoltare software și îmbunătățirea calității sistemelor dezvoltate. Interesul pentru instrumentele și mediile CASE se bazează pe așteptările privind creșterea productivității, îmbunătățirea calității produselor, facilitarea întreținerii și a face sarcina inginerilor de software să fie mai puțin odioasă și mai plăcută.
  12.  
  13. constructia software (un proces cu 3 faze)
  14. 1) design detaliat
  15. 2) cod, unitati de testare
  16. 3) compoziția soluției
  17.  
  18. 1)
  19. design nivel 1 : proiectarea sistemului general (un black box mare)
  20. design nivel 2,3,4 (detaliat)
  21. nivel 2 -> design la nivel de subsystem / pachet
  22. nivel 3 -> design la nivel de clasa
  23. nivel 4 -> design la nivel de date si de functii
  24.  
  25. 2) cod si testare pentru unitate, planificarea integrarii si testarea la nivel de subsistem
  26. integrarea sistemului și planificarea testării
  27.  
  28. DESIGN
  29.  
  30. obiectiv : obtinerea unui (sub)system bun
  31. reutilizarea resurselor existente
  32. metode iterative try-error si divide et impera
  33. complexitate : abordari top-down sau bottom-up
  34. programatorii priceputi : folosesc euristice
  35.  
  36. caracteristici de proiectare dezirabile (de dorit) (caracteristici de design intern și extern)
  37. --------------------------------------------------------------------------------------------------------------
  38. caracteristici de design extern:
  39.  
  40. availability -> disponibilitate
  41. reliability -> fiabilitate
  42. performance -> performanta
  43. fault tolerant -> toleranta la erori
  44. maintainability -> mentenabilitate (proprietate a unui produs de a fi întreținut și reparat cu ușurință)
  45. robustness -> robustete (rezistent la munca)
  46. security -> securitate
  47. interoperability -> interoperabilitate (abiliatea proceselor de a lucra împreună pentru realizarea unui scop comun)
  48. portability -> portabilitate
  49. usability -> uzabilitate
  50. functionality -> functionalitate
  51. system integrity -> integrarea sistemului
  52. consistency -> consistenta
  53. efficiency -> eficienta
  54. --------------------------------------------------------------------------------------------------------------
  55. caracteristici de design intern:
  56.  
  57. complexitate minima : cuplaj liber între piesele de proiectare si coeziune ridicată
  58. coeziune = legatura interna stransa
  59.  
  60. metrice pentru masurarea complexitatii :
  61. (fan-in, fan-out)
  62. fan-in (numarul maxim de intrari care se pot accepta)
  63. fan-out (numarul maxim de intrari care pot fi conectate la iesire, care pot fi apelate)
  64.  
  65. extensibilitate / scalabilitate
  66. reutilizabilitate
  67. stratificare
  68. tehnici standard
  69. ușurință de întreținere
  70. --------------------------------------------------------------------------------------------------------------
  71. modele de calitate
  72. McCall (1977), Boehm (1978), ISO 9126 (1990), Dromey (1996)
  73.  
  74. o euristica este orice abordare a rezolvării problemelor sau a descoperirii de sine care utilizează o metodă practică care nu este garantată a fi optimă, perfectă sau rațională, dar care este totuși suficientă pentru atingerea unui obiectiv imediat, pe termen scurt.
  75.  
  76. euristici principale : vezi curs
  77.  
  78. paradigme de programare :
  79.  
  80. obiectiv : prezentarea principalelor modele de calcul și paradigma de programare
  81. alegerea limbajului de programare potrivit
  82. - problema dificila
  83. - probmela -> programarea maparii limbajului
  84.  
  85. 1) programare secventiala
  86.  
  87. executa o declaratie la un moment dat (folosit pe un single-processor)
  88. transforma datele de intrare in rezultate conform algoritmului implementat.
  89. de obicei determinist
  90.  
  91. determinism -> fenomenele sunt generate de înlănțuiri de cauze și efecte, prin condiționări și legități, prin interacțiuni necesare și repetitive.
  92.  
  93. 2) programare concurenta
  94.  
  95. entitatile de programare se executa simultan (in paralel)
  96. schimb de informații dinamic
  97. o mare varietate de modele concurente
  98. suport de executie
  99. transforma secvențial în programare simultană (efort de cercetare pentru automatizarea acestei lucrări)
  100. strategie de descompunere a sarcinilor mari în mai multe sarcini mai mici care se execută concomitent.
  101. alocarea sarcinilor mai mici mai multor lucrători pentru a lucra simultan.
  102.  
  103. --------------------------------------------------------
  104. clase de algoritmi și probleme, paralele și distribuite
  105. --------------------------------------------------------
  106. 1) programare paralela
  107.  
  108. formă specială de programare concurentă (multiple procesoare fizice), (partajarea memoriei)
  109.  
  110. abordări pentru construirea aplicațiilor paralele :
  111. paralelismul funcțional
  112. paralelism master-slave
  113. paralelism spmd (same code replicated)
  114.  
  115. principalele sarcini de programare paralelă :
  116. descompunerea, distribuirea si coordonarea task-urilor / sarcinilor
  117.  
  118. 2) programare distribuita
  119.  
  120. formă specială de programare concurentă (multiple procesoare fizice) (situata de la distanță) (fara partajare a memoriei)
  121. comunicarea intre procese (canale de comunicatie) (schimbul de mesaje)
  122.  
  123. --------------------------------------------------------------
  124. clase de algoritmi și probleme, transformaționale și reactive
  125. --------------------------------------------------------------
  126. 1) programare transformațională
  127.  
  128. bazata pe secventa : citeste date, proceseaza date, furnizeaza rezultate
  129. pot fi văzute ca funcții ale n intrări care generează m ieșiri
  130. comportamentul programului depinde de starea curentă a programului și de intrare
  131. poate fi paralelizat
  132.  
  133. 2) programare reactiva
  134.  
  135. interacționează cu mediul în timpul executării
  136. nu poate fi specificata ca o funcție
  137. programare condusă de evenimente
  138. inerent nedeterminist
  139.  
  140. -------------------
  141. modele de calcul
  142. -------------------
  143. programare orientată procedural, imperativ -> proceduri, algoritmi, principiul substitutiei (Pascal, C, C++)
  144. programare orientata pe obiect -> obiecte si clase (Simula, SmallTalk, C++, Java, C#)
  145. programare functionala -> functii, calcul cu lambda (Lisp, ML, Haskel)
  146. programare logica -> foloseste calculul predicatului (Prolog, SQL)
  147. programare orientata pe constrangeri -> relații invariante
  148.  
  149. programare functionala (caracteristici principale)
  150.  
  151. funcții de ordin superior - functii care iau alte functii ca argumente sau tip returnat
  152. date imuabile - în loc să modifice valorile existente, limbajele funcționale operează adesea pe o copie a valorilor originale pentru a le păstra
  153. concurenta - este mai simplu de implementat, datorata datelor imuabile
  154. transparență referențială - calculele pot fi efectuate în orice moment, producând întotdeauna același rezultat (similar cu metodele statice din Java)
  155. evaluare leneșă - valorile pot fi calculate numai atunci când este necesar, deoarece funcția poate fi evaluată oricând, oferind mereu același rezultat
  156.  
  157. programarea reactiva
  158. concepte principale: fluxuri de date și propagarea modificărilor de date
  159. pentry x = y + z; daca se schimba valorile lui y si z atunci valoarea lui x se va modifica si ea.
  160. codul gestionează valorile în timp ce acestea variază în timp, propagând modificări la fiecare parte a codului care folosește aceste valori
  161. poate fi implementate in multe limbaje de programare : Java, JavaScript, C#, SCala, C++, Python, etc.
  162. combină modelul de observare, modelul de iterator și programarea funcțională
  163. utilizează observeri pentru a reprezenta fluxuri de date asincrone
  164. abstractizeaza toate detaliile threading-ului, concurentei si a sincronizarii.
  165. permite scrierea ușoară a programelor concurente
  166.  
  167. TP Curs 2
  168.  
  169. diagrama use case -> surprinde cerințele și ilustrează interacțiunile utilizatorilor cu sistemul
  170. diagrama de clase si de obiecte -> ilustreaza structura logica a sistemului
  171. diagrama de secvență, colaborare si de stare -> ilustreaza comportamentul sistemului
  172. diagrama de activitate -> ilustrează fluxul evenimentelor într-un caz de utilizare
  173. diagrama de pachete -> arată pachete de clase și dependențele lor
  174. diagrama de componente -> ilustrează structura fizică a software-ului
  175. diagrama de implementare -> arată maparea software-ului la configurațiile hardware
  176.  
  177. diagrame de clase si de obiecte
  178.  
  179.  
  180. descriu clasele și obiectele din sistem și relațiile dintre ele
  181. relatii (asociere, agregare/compozitie, generalizare (mostenire), realizare, dependenta)
  182. o clasa poate arata (atribute, operatii, constrangeri)
  183. (+) -> camp public, (-) -> camp privat, (#) -> camp protected, (+) -> metoda publica, (-) -> metoda privata
  184.  
  185. asocieri
  186.  
  187. folosirea asocierilor (trei scopuri generale) reprezinta :
  188. 1) o situatie in care un obiect de o clasa foloseste serviciile unui alt obiect, sau ele isi folosesc reciproc serviciile - adica un obiect ii trimite mesaje celuilalt sau isi trimit mesaje intre ele. (in primul caz, navigabilitatea poate fi unidirectionala, il cel de-al doilea trebuie sa fie bidirectionala)
  189. 2) agregarea sau compozitia - unde obiecte de o clasa sunt intregi compusi din obiecte de cealalta clasa ca parti.
  190. 3) o situatie in care obiectele sunt inrudite, chiar daca nu schimba mesaje. Aceasta se intampla de obicei cand cel putin unul dintre obiecte este folosit in esenta la stocare de informatie.
  191.  
  192. asociere bidirectionala daca avem clasele
  193.  
  194. public class ResearchProj
  195. {
  196. private Professor theProfessor;
  197. public ResearchProj() { ... };
  198. }
  199.  
  200. public class Professor
  201. {
  202. private ResearchProj[] rp = new ReasearchProj[MAX_RP];
  203. public Professor() { ... };
  204. }
  205.  
  206. unidirectionala ar fi fost daca nu declaram variabial theProfessor in clasa ResearchProj
  207.  
  208. Agregare = mecanismul prin care definim oclasă nouă ce include una sau mai multe date membre care au ca tip clase deja definite.
  209. Ne permite construirea de clase complexe pornind de la clase mai simple
  210. relatie de tip "are o\un"
  211. o forma speciala de asociere care modeleaza relatia parte-intreg intre un agregat (intregul) si partile sale
  212. intregul e cel la care se marcheaza rombul
  213. proprietati agregare : tranzitivitate, nereflexivitate
  214.  
  215. Realizare -> o interfata serveste post de contract pe care o clasa este de acord sa-l indeplineasca
  216.  
  217. Dependenta -> relatie de tip "foloseste". O relaţie între două elemente ale modelului în care o
  218. schimbare în unul dintre elemente poate cauza o schimbare în celălalt (de ex Client -> Furnizor)
  219. (StudentReportGenerator -> Student)
  220.  
  221. forward engineering -> de la uml trecem la implementarea metodelor
  222.  
  223.  
  224. diagrame de interacțiune
  225.  
  226. descriu modul în care grupurile de obiecte colaborează
  227. surprinde de obicei comportamentul unui singur caz de utilizare
  228. arată obiectele implicate și mesajele transmise printre obiecte
  229. arată colaborarea dintre obiectele unui caz de utilizare
  230.  
  231. diagrame de secventa
  232.  
  233. arată obiectele implicate în interacțiune
  234. linie verticala punctata sub obiecte
  235. fiecare mesaj mută fluxul de control de la un obiect la altul
  236. un use-case poate avea mai multe scenarii (de ex cand cumperi un produs de la vending machine si nu ai de primit rest, ar fi un best-case scenario)
  237.  
  238. diagrame de activitate
  239.  
  240. stare de îndeplinire a unor sarcini
  241. diagramele de activitate descriu secvențe de activități
  242. suport pentru un comportament condiționat și paralel
  243.  
  244. branch - ramura
  245.  
  246. un punct de decizie la care există două sau mai multe căi de flux de control posibile
  247. branch-ul este exclusiv mutual
  248.  
  249. merge - combinare
  250.  
  251. multiplica tranzitia de intrare, are un iesire unica
  252.  
  253. fork
  254.  
  255. când tranziția de intrare este declanșată, tranzițiile de ieșire sunt luate în paralel
  256. poate specifica programarea concomitentă
  257.  
  258. diagrame de pachet
  259.  
  260. ajuta la descompunerea sistemelor mari în subsisteme
  261. un pachet este o colecție de elemente de modelare care sunt grupate togheter deoarece acestea sunt legate în mod logic
  262. la definirea pachetelor, ar trebui aplicate principiile coeziunii și cuplării
  263.  
  264. diagrama de componente
  265.  
  266. o diagramă a componentelor arată modul în care componentele sistemului se raportează între ele
  267. diferenta intre diagrama de componente si cea de pachete :
  268. diagrama de pachete : grupare logică a elementelor de proiectare.
  269. diagrama de componente : componente fizice
  270.  
  271.  
  272. diagramele de componente pot fi combinate cu diagrame de desfășurare pentru a arăta locația fizică a componentelor sistemului
  273.  
  274. deployment diagrams - diagrame de implementare
  275.  
  276. arată arhitectura fizică a sistemului
  277. arată configurația elementelor de procesare în timp de rulare și a componentelor și proceselor software localizate pe acestea
  278. configurația arată nodurile și asociațiile de comunicare
  279. nodurile sunt utilizate de obicei pentru a afișa calculatoare, în timp ce asociațiile de comunicare arată rețeaua și protocoalele utilizate pentru a comunica între noduri
  280. diagramele de implementare pot afișa fie tipuri de mașini, fie numele lor și componentele active dintre noduri
  281.  
  282. mostenirea si polimorfismul
  283.  
  284. o subclasa extinde caracteristicile superclasei sale
  285. fiecare instanta a subclasei este o instanță a superclasei și nu invers
  286.  
  287. substituibilitatea subtipurilor
  288.  
  289. o valoare a unui subtip poate apărea oriunde este de așteptat un supertip
  290. un obiect subclasa poate apărea oriunde este de așteptat un obiect supercalzant
  291. o instanță a unei subclase poate întotdeauna înlocui o instanță a superclasei sale
  292.  
  293. widening
  294. conversia unui subtip la unul dintre supertipurile sale
  295.  
  296. downcasting
  297.  
  298. conversia unui supertip la unul dintre subtipurile sale
  299. are nevoie de un cast explicit (nu este sigur intotdeauna, paote genera exceptii)
  300.  
  301. polimorfismul are 2 tipuri principale
  302. 1) universul
  303. polimorfismul universal are 2 subtipuri
  304. a) parametric -> o funcție funcționează uniform într-o serie de tipuri care prezintă o structură comună (generic)
  305. b) includere -> o funcție funcționează uniform pe o serie de tipuri guvernate de relația subtipului
  306. 2) ad-hoc
  307. polimorfismul ad-hoc are 2 subtipuri
  308. a) overloading (supraincarcarea) -> folosind o funcție cu același nume, dar parametri diferiți și cod diferit, decizia de a selecta o funcție depinde de parametrii de apel
  309. b) coercion (constrangere) -> un obiect sau primitiv este aruncat într-un alt tip'
  310.  
  311.  
  312. polimorfism - binding (linking)
  313.  
  314. legarea statică - tipul unui obiect este determinat în timpul compilării de către compilator
  315. legare dinamică - tipul unui obiect este determinat în timpul rulării
  316.  
  317. Clase Abstracte si interfete
  318.  
  319. o clasă abstractă Java este o clasă declarată cu cuvântul cheie abstract care poate include metode abstracte
  320. o metoda abstracta nu are implementare
  321. clasele abstracte nu pto fi instnatiate in obiecte
  322. referințele la clase abstracte pot fi utilizate pentru a defini parametrii în metode
  323. toate metodele abstracte sunt mostenite si trbeuie definite in subclase
  324. o clasă care implementează o interfață, dar care nu implementează toate metodele interfeței, trebuie declarată abstractă.
  325.  
  326. o interfață java este un tip de referință, similar cu o clasă, care poate conține numai
  327. 1) constante
  328. 2) metode abstracte fara implementare
  329. 3) metode default (implicite)
  330. definit cu cuvântul cheie implicit la începutul semnăturii metodei
  331. poate fi utilizat în cazul adăugării de noi funcționalități la o interfață, specificând o implementare implicită pentru noua metodă pentru a evita ruperea codului
  332. 4) metode statice (cu implementare)
  333. 5) metode private (cu implementare)
  334.  
  335. metode abstracte
  336.  
  337. toate declarațiile metodei interfeței sunt implicit abstracte și publice, cu excepția cazului în care sunt declarate statice sau implicite
  338. metoda abstractă a unei interfețe sunt moștenite de clasele care implementează interfața și clasificate le înlocuiesc pentru a oferi o implementare
  339.  
  340. metode statice
  341.  
  342. declarația metodei statice conține modificator static (implicit public)
  343. metodele statice dintr-o interfață nu sunt moștenite de clasele de implementare sau subinterfețele
  344. există o singură modalitate de a apela la metoda statică a unei interfețe - folosind numele interfeței
  345.  
  346. metode default (implicite)
  347.  
  348. permit evoluția interfețelor existente
  349. o metodă implicită poate fi adăugată la o interfață existentă pentru a furniza o implementare implicită a metodei
  350. toate clasele care implementează interfața vor moșteni implementarea implicită
  351. clasele pot alege să înlocuiască implementarea implicită
  352.  
  353.  
  354. metoda implicită în interfață versus o metodă concretă a unei clase care implementează interfața
  355. similaritati : amandoua vin cu o implementare, amandoua metode isi pot folosii parametrii si pot arunca exceptii.
  356. deosebiri : accesul la starea obiectului, o metodă implicită nu are acces la instanța variabilelor clasei care implementează interfața, o metodă concretă poate accesa variabilele de instanță ale clasei, metoda implicită are acces la ceilalți membri ai interfeței, de exemplu alte metode, constante și membri de tip
  357.  
  358. metode private
  359.  
  360. nu este mostenita deci nu poate fi suprascrisa, si nici o metoda finala nu poate fi suprascrisa
  361. o metodă implicită este o metodă de instanță și oferă o implementare implicită. este menit să fie supraîncărcata
  362. puteți avea o metodă privată într-o interfață care este fie o metodă de instanță non-abstractă, care nu este implicită sau o metodă statică
  363.  
  364. interfete functionale
  365.  
  366. o interfata functionala este o interfata ce are doar o metoda abstracta
  367. metodele statice și cele implicite nu sunt luate în considerare pentru a desemna o interfață sau o interfață funcțională
  368. se poate pune inainte de declaratie @FunctionalInterface
  369. compilatorul va verifica interfața adnotată conține într-adevăr o singură metodă abstractă, în caz contrar, declarația de interfață nu va fi compilată
  370.  
  371. interfete marker (marcator) -> interfete fara metode declarate (ex Serializable, Cloneable)
  372.  
  373. interfete - reguli
  374.  
  375. toate metodele declararile metodele abstracte într-o interfață sunt publice
  376. interfetele nu pot fi instantiate
  377. variabilele de referință pot avea ca tip o interfață, dar orice obiect atribuit acestora trebuie să fie instanțe ale unei clase care implementează interfața
  378.  
  379. C, C1, C2 sunt clase
  380. I, I1, I2 sunt interfete
  381. T, T1, T2 sunt tipuri (primitive / referinte)
  382. C1 extinde C2 => C1 este un subtim de a lui C2
  383. I1 extinde I2 => I1 este un subtip al lui I2
  384. C implementeaza I => C este un subtip al lui I
  385. pentru fiecare I => I este un subtim al obiectului
  386. pentru fiecare T => T[] este un subtip al obiectului
  387. daca T1 este un subtip al lui T2 => T1[] este un subtim al lui T2[]
  388. pentru fiecare C care nu este obiect => C este un subtip al obiectului
  389.  
  390.  
  391. moștenire în formă de diamant
  392.  
  393. interfata vs clasa abstracta
  394.  
  395. asemanari :
  396.  
  397. ambele definesc un contract care trebuie implementat de o clasă
  398. interfata nu descrie rolul principal al clasei
  399. clasa abstracta definește identitatea de bază a urmașilor săi
  400. interfata specifica ce poate face clasa, nu si ce este.
  401. subclasele unui clase abstracte sunt omogene
  402. subclasele interfetei sunt heterogene
  403.  
  404. mostenire -> caracteristici principale
  405.  
  406. un utilizator ar trebui să studieze pentru a înțelege metodele superclasei sale
  407. mai putin cod
  408. operatiile sunt mai dificil de inteles
  409. multe metode sunt deja implementate
  410.  
  411. dezavantaje
  412.  
  413. sparge încapsularea, deoarece expune o subclasă la detaliile de implementare a superclasei sale
  414. legătura dintre clasa copilului și clasa părintească este stabilită în timpul compilării
  415. este posibil ca subclasele să fie modificate dacă se modifică implementarea superclasei
  416. implementările moștenite de la superclase nu pot fi schimbate la runtime ca blocuri de compoziție
  417.  
  418. agregare - avantaje
  419. obiectele conținute sunt accesate de clasa conținând numai prin interfețele lor
  420. incapsulare buna
  421. compoziția poate fi definită dinamic la timpul de rulare prin obiecte care se referă la alte obiecte de același tip
  422. dezavantaje - sistemele rezultate tind să aibă mai multe obiecte
  423. - interfețele trebuie definite cu atenție pentru a utiliza mai multe obiecte diferite ca blocuri de compoziție
  424. concluzie (compozitie > mostenire)
  425.  
  426. obiective de proiectare poo
  427.  
  428. reutilizabitate, flexibilitate, generalitate (cu efort minim), extensibilitate
  429. design patterns (DP) (modele de design ajuta la atingerea acestor obiective)
  430.  
  431. nivel inalt -> framework
  432. nivel mediu -> design patterns
  433. nivel scazut -> clase
  434.  
  435. soluții recurente pentru a crea probleme pe care le vedeți de mai multe ori
  436. set de reguli care descriu modul de îndeplinire a anumitor sarcini pe tărâmul software-ului
  437. un model de proiectare abordează o problemă de design recurentă care apare în situații de proiectare specifice și îi prezintă o soluție
  438.  
  439. modele de creație
  440. ajuta la crearea obiectelor folosind niveluri de creare indirectă (subclase sau alte obiecte)
  441.  
  442. modele structurale
  443. ajuta la compunerea grupurilor de obiecte în structuri mai mari
  444.  
  445. modele comportamentale
  446. ajută la definirea comunicării între obiecte și, de asemenea, ajută la controlul fluxului programelor complexe
  447.  
  448. exemple modele de creatie :
  449.  
  450. abstract factory -> generarea de familii de obiecte înrudite sau dependente (obiecte de produs) fără a specifica clasa lor concretă
  451.  
  452. builder / constructor -> folosit pentru a genera obiecte compozite. Separa construcția unui obiect complex de reprezentarea sa, astfel încât același proces de construcție poate crea reprezentări diferite
  453.  
  454. factory method / virtual constructor -> definește o interfață pentru crearea unui obiect, dar permite subclaselor să decidă ce clasă trebuie să se instanteze. Permite unei clase să amâne procesul de instantanare subclaselor
  455.  
  456. prototype -> specificați obiectele pe care să le creați folosind o instanță prototipică și creați obiecte noi prin copierea acestui prototip
  457.  
  458. singleton -> crearea de obiecte unice dintr-o anumită clasă
  459.  
  460. exemple modele structurale :
  461.  
  462. adapter / adaptor -> invelirea obiectelor într-o interfață nouă. Convertește interfața unei clase într-o altă interfață pe care o așteaptă clienții. Adaptorul permite ca clasele să funcționeze în alt mod, din cauza interfețelor incompatibile
  463.  
  464. bridge / pod -> decuplează o abstractizare de la punerea în aplicare a acesteia, astfel încât cele două să poată varia independent
  465.  
  466. composite -> compune obiecte în structuri de arbori pentru a reprezenta ierarhii parțiale. Composite permite clienților să trateze uniform obiecte individuale și compoziții de obiecte
  467.  
  468. decorator -> atașează responsabilități suplimentare unui obiect într-un mod dinamic. oferă o alternativă flexibilă la subclase pentru extinderea funcționalității
  469.  
  470. facade / fatada -> furnizeaza o interfață unificată unui set de interfețe dintr-un subsistem. Fațada definește o interfață de nivel superior care face mai ușor utilizarea subsistemului
  471.  
  472. flyweight -> utilizeaza distribuirea pentru a susține eficient un număr mare de obiecte cu granulație fină
  473.  
  474. proxy / imputernicirea -> furnizează un surogat sau un locatar pentru un alt obiect care să controleze accesul la acesta. utilizat pentru accesarea obiectelor la distanță sau costisitoare
  475.  
  476. exemple modele comportamentale
  477.  
  478. command -> încapsulează o solicitare ca obiect. folosește obiecte pentru a reprezenta operațiunile
  479.  
  480. chain of responsibility / lanț de responsabilitate -> evită cuplarea expeditorului unei solicitări la receptor. Definește un lanț de obiecte care au dreptul să cunoască și să proceseze solicitarea până când un obiect o gestionează. obiectul care va procesa solicitarea nu este cunoscut la momentul proiectării
  481.  
  482. iterator -> încapsulează modul în care cineva traversează și accesează componentele unui obiect agregat
  483.  
  484. interpreter / interpretor -> pentru o anumită limbă definește o reprezentare a gramaticii sale și un interpret pentru utilizarea gramaticii pentru a interpreta propozițiile limbii
  485.  
  486. mediator -> încapsulează protocolul dintre un ansamblu de obiecte care au cooperat pe la colegi (în loc să-i permită pe colegi să definească referințe între ele - cuplare puternică). Obiectul mediator asigură indirecția necesară pentru cuplajul liber
  487.  
  488. memento -> surprinde și externalizează o stare internă a unui obiect. În acest fel obiectul poate fi restaurat la această stare din urmă.
  489.  
  490. observer -> definește dependența între obiecte și multe. când un obiect schimbă starea, toți dependenții săi sunt notificați și actualizați automat
  491.  
  492. state -> reprezentarea și procesarea stărilor ca obiecte
  493.  
  494. visitor / vizitator -> reprezintă o operație care trebuie efectuată pe elementele unei structuri a obiectelor
  495.  
  496. template method -> definește un schelet al unui algoritm într-o operație, postoponând câțiva pași către subclase. partea invariabilă a algoritmului ar trebui să fie implementată prin metoda tempalte și comportamentul care variază este implementat de subclase
  497.  
  498. strategy / strategie -> incapsuleasa un algoritm
  499.  
  500. ADAPTER / ADAPTOR / INVELITOR
  501.  
  502. adaptorii -> permit claselor să funcționeze care altfel nu ar putea fi din cauza interfeței incompatibile
  503. exemplu : un player audio care poate functiona doar cu fisiere mp3 si vrea sa foloseasca un program capabil sa functioneaza cu mp4.
  504.  
  505. intentia : transformă interfața unei clase într-o interfață care poate fi utilizată de o altă clasă
  506. doriți ca un client să apeleze la o metodă a unui obiect instant al unei clase care nu implementează interfața
  507.  
  508. de ex avem un client care apeleaza o metoda request() din clasa tinta
  509. clasa tinta este adaptata cu ajutorul interfetei (adapter) si va pointa catre metodele specifice din adaptee.
  510.  
  511. consecinte : adaptor lucreaza cu mai multi adaptee
  512. adaptorul poate adauga functionalitate in clasele adaptee
  513.  
  514. modelul command
  515. intentia : foloseste obiectele sa reprezinte operatii / comenzii
  516. consecinte : comenziel pot fi tratate si manipulate ca niste obiecte. un sir de comenzi poate fi reprezentat ca si o coada, stiva sau alte structuri de date.
  517.  
  518. avem un invoker (o telecomanda) care poate avea una sau mai multe interfete (comenzi) implementate in clasa command iar receiverul foloseste clasa command pentru a primi modificarile
  519.  
  520. invoker -> o clasă din acest rol creează obiecte de comandă concrete dacă trebuie să invoce o comandă
  521.  
  522. deci -> se decuplează obiectul care invocă operația de cel care știe să-l efectueze
  523.  
  524. composite design pattern
  525. (modelul compozitiei recursive)
  526. prezinta o clasa abstracta care reprezinta primitivele si compusele.
  527.  
  528.  
  529. definește ierarhiile de clase constând din obiecte primitive și obiecte compuse
  530. obiectele primitive pot fi compuse în obiecte mai complexe care, la rândul lor, pot fi compuse, etc.
  531. clienții, în mod normal, nu știu (și nu ar trebui să le pese) de ce au de-a face cu o frunză sau o componentă compozită -> se simplifica codul
  532. facilitează adăugarea de noi tipuri de componente. Subclasele de compozite sau frunze noi și definite funcționează automat cu structurile existente și codul client. Clienții nu trebuie schimbați pentru noi clase de componente
  533.  
  534. metoda factory
  535.  
  536. avem o aplicatie care luceaza cu niste documente. acest factory doreste ca aplicatia sa nu fie hardcodata, sa nu fie legata direct de documentele cu care lucreaza, nu aplicatia respectiva sa invoce new pe documentul pe care vrea sa-l utilizeze. sa apeleze la o fabrica de documente si acea fabrica sa produca respectivul document.
  537. vrem sa decuplam o clasa de entitatile pe care le utilizeaza. sa i le creeze altcineva pentru ea.
  538.  
  539. avem o aplicatie si o interfata sau o clasa abstracta documentfactory si o clasa care implementeaza metoda createdocument definita in interfata (documentfactory) si aplicatia cere acestui factory (request creation) sa ii creeze un document cu care sa lucreze. aplicatia va primi o referinta a documentului creat
  540.  
  541. acest model de metodă furnizează unui obiect independent de aplicație un obiect specific aplicației la care poate delega crearea altor obiecte specifice aplicației
  542.  
  543. product -> superclasa abstracta a obiectelor produse de factory method
  544.  
  545. interfata factory -> aplicație independentă clasă abstractă sau interfață
  546.  
  547. un exemplu : creationrequester care este factorypatterndemo care cere shapefactory sa creeze obiecte care sunt subclase ale lui shape. creationrequester e clasa cu metoda main care interactionaza cu shape
  548.  
  549. design patter proxy (model proxy)
  550.  
  551. (reprezinta niste entitati mai complexe) (un proxy este un surogat, un reprezentat al cuiva)
  552. anecdota comunism : ce este sampania? sampania este bautura pe care o beau masele populare prin reprezentatii lor (prin proxy lor)
  553.  
  554. clientul in primul rand se adreseaza proxy, iar daca proxy nu poate sa raspunda atunci trimite acea cerere spre serviciul adevarat.
  555.  
  556. clienții proxy nu știu că au de-a face cu un surogat în locul obiectelor reale de care au nevoie
  557. clasa proxy și clasa pe care o reprezintă (serviciul clasei) au aceeași interfață sau aceeași superclasă
  558.  
  559. daca am o aplicatiei care se executa local si cere executia unei metode de pe un svr indepartat. mai intai cere operatia respectiva proxy-ului local. acesta verifica parametrii (verifica daca sunt de tipul cerut) (nu mai are rost sa se mai trimita spre retea acele date pentru ca eroarea poate fi data de proxy)
  560. astfel se salveze sau se economiseste transmiterea pe retea a datelor (trimiterea dus-intors pe retea este scumpa)
  561. obiecte scumpe (constructia lor ia multe resurse si mult timp)
  562. daca proxy-ul poate sa raspunda atunci raspunde.
  563.  
  564. in cazul in care se utilizeaza un site. de multe ori pagina respectiva este memorata intr-un cache local a.i nu mai este adusa pagina dintr-un site indepartat ci dintr-un cache local numit proxy
  565.  
  566. avem o interfata de tip imagine (implementata atat de o imagine reala cat si de o imagine proxy) daca imaginea este deja in proxy adica in cache este adusa de acolo, daca nu se merge dupa imaginea reala, oriunde s-ar afla ea)
  567.  
  568. prin această indicație, obiectul client nu este conștient de faptul că obiectul de serviciu nu a putut fi creat atunci când operația este invocată și procesată de obiectul proxy
  569.  
  570. modulul singleton
  571.  
  572. in multe situatii avem obiecte unice (o masina are un singur volan) (un calculator are un singur sistem de operare). datorita faptului ca avem situatii multe in care trebuie sa creem un singur model.
  573. cum creem o singura instanta dintr-o clasa
  574. numele metodei care creeaza instanta unica se numeste instance.
  575. pattern-ul singleton pt implementarea lui necesita ca limbajele de programare sa poata defini date statice.
  576.  
  577. clasa singleton defineste referinta oneObject la un singur obiect
  578. constructorul clasei este de tip private
  579. si metoda instance este generatoarea obiectului unic
  580. daca oneObject e null (nu a fost generat) se apeleaza constructorul este ok daca e privat il apelez dintr-o metoda proprie clasei.
  581.  
  582. se genereaza eroarea daca apelam Singleton s = new Singleton(); (constructorul este privat)
  583.  
  584. cealalta varianta este folosind exceptii
  585. clasa singleton arunca singletonexception i ncazul in care se incearca crearea unui alt obiect de tip singleton.
  586. clasa singleton ascunde singura operație de creare a insatenării în spatele unei metode de membru static
  587.  
  588. inversiunea controlului
  589.  
  590. fundamentala in dezvoltarea aplicatiilor software moderne.
  591. se inverseaza diferite tipuri de controlare in poo (fluxul unui aplicatii, fluxul crearii de obiecte)
  592. toate cu scopul de a avea clase care sunt mai putin cuplate pentru a putea fi mai bine testate, mai bine intretinute si mai extensibile
  593.  
  594. inversion of control poate sa fie implementat in 3 moduri
  595. 1) tehnici numitie injectie de dependinte
  596. 2) tehnici de tip locator
  597. 3) tehnici de tip callback
  598.  
  599. 1) injectare de dependinte
  600. o clasa a si o clasa b
  601. pentru ca sa avem clasa a utilizand clasa b avem 2 modalitati
  602. in primul caz (dependenta hardodata) -> clasa a creaza direct obiectul b de care are nevoie (controlul este la nivelul clasei a) (fie il creeaza direct fie prin intermediul unui factory method)
  603. in celalalt caz o entitate externa este in controlul generarii elementului de tip b de care are nevoie clasa a. in constructorul clasei a, obiectul de tip b este injectat in constructor de catre o entitate exterioara.
  604. aceasta injectie poate fi fie cu parametru in constructor fie cu metode de tip set.
  605.  
  606. clasa myprogram are metoda main in care creeaza o variabila de tip client si injectieaza serviciul in client new Client(new Service(..));
  607. serviciul implementeaza o interfata IService cu metoda serve()
  608. clientul apeleaza start, executa serviciul. deci myprogram genereaza clientul injectand serviciul in client
  609.  
  610. 2) service locator (locatoare de servicii)
  611. un locator de serviciu e un software care permite dezvoltarea de cod slab cuplat
  612. daca am un program care are nevoie de un serviciu si nu stie unde sa il gaseasca -> foloseste un locator.
  613. in tehnica anterioarea myprogram cunostea serviciul, aici myprogram nu cunoaste exact serviciul (tehnica fundamentala pentru arhitecturile SOA (Service Oriented Architecture)
  614.  
  615. myprogram cere clientului sau sa-i rezolve o problema, generand un nou client, parametrii indica problema de rezolvat, clientul folosestii respectivii parametrii pentru a apela un locator care sa-i localizeze un serviciu care stie sa-i rezolve problema respectiva. locatorul localizeaza serviciul si il injecteaza. in client.start() are deja clientul serviciul injectat si il executa.
  616. SL = Service Locator
  617. parametrii aceia pot fi de tipul quality of service (cat de rapid sa fie sau cat de rapid sa se execute).
  618.  
  619. service oriented architecture (SOA)
  620.  
  621. un service provider (furnizor de servicii) (poate fi o intreprindere) isi inregistreaza serviciile disponibile intr-un broker (care va functiona ca si un SL service locator). acesti service provider pot fi diferite firme (transport, warehouse, acomodare) si vin pe urma niste clienti, care pot fi tot firme sau persoane fizice si cauta niste servicii. cautarea este facuta pe baza acestui locator. i se returneaza customer-ului cel mai bun serviciu. ii va returna customerului acesta si lasa pe customer sa invoce serviciul respectiv al provider-ului.
  622.  
  623. neajunsurile abordarilor DI si SL (dependency injection si service locator)
  624. rezulta din hardcodare (un utilizator care doreste sa utilizeze DI si SL trebuie sa isi gestioneze sigur dependintele) management-ul acestor dependinte este dificil daca sunt prea multe
  625. daca vrem sa modificam o clasa se depinda de alta noua, toate aceste modificari trebuie facute cu mana, recompilat. putem sa avem de a face cu sisteme cu sute/mii de asemenea dependinte intre clase. este necesara o automatizare a acestor dependinte
  626.  
  627. solutia ? containere cu management automat (framework spring care foloseste un IoC container pt managementul automat al dependintelor).
  628.  
  629. 3) IoC (inversion of control cu callback)
  630.  
  631. obiectivul este sa informam o clasa ca intr-o alta clasa s-a intamplat un eveniment.
  632. sa apelam o alta functie dintr-o clasa care sa se execute atunci cand un eveniment se intampla intr-o alta clasa.
  633.  
  634. tehnica folosita in java pentru programarea bazata pe evenimente in care functia chemata de alta clasa este de fapt listener-ul sau handler-ul de evenimente.
  635.  
  636. callback -> o functie/metoda f care este transmisa ca argument unei alte functii g si f se asteapta sa fie executata dupa ce s-a intampla un eveniment la nivelul functiei g (definitia corecta a callbackului)
  637. este utilizata in task-uri asincrone (dar in java non-functional metodele nu pot sa fie pasate ca parametri).
  638. dar folosind expresii lambda putem pasa acest lucru.
  639.  
  640. exemplu : interfata IF defineste metoda f() care trebuie sa se execute la callback, avem un listener care implementeaza interfata (arata cum este implementeaza metoda f) si pe urma avem o aplicatie care functioneaza pe post de notifier (notifica listener-ul cand se intampla ceva, care include o referinta de tip interfanta si o metoda de inregistrare a functie de callback si o metoda de buisness in care se intampla evenimente.
  641.  
  642. main-ul instantiaza un listener, instantiaza o aplicatie, inregistreaza cu aplicatia listener-ul dupa care zice sa se execute operatie de buisness. in timpul situatie de buisness se intampla acest eveniment, si folosind aceasta referinta inregistrata se apeleaza listener-ul handler-ul care stie sa trateze situatie care s-a creat in timpul executiei buisness. (butoane la GUI de ex)
  643.  
  644. Observer design pattern
  645.  
  646. acest design este utilizat atunci cand avem dependinte one to many -> atunci cand partea one se modifica, dorim ca si partile many asociate cu partea one sa fie informate ca sa se poata modifica
  647.  
  648. avem o serie de observatori care in momentul in care se modifica o valoare dintr-un array, se asteapta sa fie informati pt a putea modifica reprezentarea grafica a dependentei respective (cum se schimba un grafic in excel)
  649.  
  650. daca avem un warehouse , un depozit de legume si fructe (partea one) partea many ar fi niste magazine de cartier care se aprovizioneaza de la depozit. acele magazine vor sa fie informate in anumite momente.
  651. asta face design pattern-ul observer
  652. realizeaza aceasta dependinta one to many si instiinteaza componentele many ori de cate ori se modifica elemente din partea one (se mai numeste si publish - subscriber) (unul publica iar celalalt este abonat)
  653.  
  654. componenta one este subiectul (subject) iar componenta many sunt observatorii
  655. clasa abstracta subiect are metodele de atasare si detasare de observator si notify.
  656. ea este subclasificata de catre subiecti concreti
  657. subiectii concreti definesc metodele getState() si setState() si au o variabila de instanta subjectState (cate tone de banane, sau au venit banane). metoda notify este apelata de fiecare data cand se executa metoda setState() dintr-un subiect concret. in momentul in care a sosit camionul si a descarcat se actualizeaza cu noul tonaj descarcat iar in setState vom gasi un apel la notify. Observer are o lista de observatori. pentru toti observatorii din acea lista apeleaza metoda update definita in clasa observer.
  658.  
  659. observatorul concret are o referinta la subiectul pe care il monitorizeaza, pentru ca metoda update foloseste aceasta referinta pentru a afla de fapt ce s-a intamplat cu subiectul pe care il urmareste.
  660.  
  661. daca am un observator care e interesant pe mai multi subiecti.
  662. nu putem sa luam acest schelet si sa il punem direct in acea aplicatia fara sa adaptam. cine activeaza activarea, cine e responsabil de acel triggering? cat de multa informatia e transmisa de la subiect la observator?
  663.  
  664. model push -> toate modificarile subiectului sunt impinse spre observator
  665. model pull -> observatorul este informat numai ca s-a informat ceva si lasat sa-si treaca singuru caracteristicile care il intereseaza.
  666. se furnizeaza suport sub forma unui clase Observable si a unei interfete Observer
  667. incepand cu java 9 aceste structuri sunt deprecated (adica java nu le va mai considera pentru a fi utilizate in dezvoltarile lor)
  668.  
  669. se poate implementa de la 0 acel design pattern (fara a folosi clasele si interfetele deprecated)
  670. alta varianta -> property change listener (o interfata definita in Java Beans)
  671.  
  672. Observable a fost date unei clase si nu interfetei, iar numele interfetei este Observer (trebuia sa fie pe dos) (ii iertam haha)
  673. interfetele ar trebui sa se termine cu -able
  674.  
  675. interfata Observer defineste metoda update
  676. clasa Observable defineste o variabila instanta state si un constructor care construieste un obiect Observable fara observatori.
  677. defineste metodele addObserver, deleteObserver si notifyObservers.
  678. notify este apelat de fiecare dat cand se executa setState() si apeleaza update, pasand niste argumente
  679. notifyObservers ia ca si parametru un obiect (variabila de instanta care s-a modificat) (pretul sau cantitatea de ex) si apeleaza metoda update definita de observator si paseaza this (ascuns) care inseamna de fapt referinta la subiectul concret si parametrul care s-a modificat (pretul , cantitatea de ex)
  680. notify fara parametru, spune numai observatorului ca s-a modificat si lasa observatorul sa traga singur de ce are nevoie (pret sau cantitate)
  681. mai apar 3 metode, hasChanged, setChanged si clearChanged() care lucreaza pe variabila instanta state
  682. hasChanged returneaza valoarea lui state. valoarea lui state e modificata cand se apeleaza setChanged(). clearChanged() este o metoda care intoarce state-ul pe fals si se executa automat de fiecare data cand se executa notifyObservers. adica dupa ce acestia sunt notificati, se pune pe fals.
  683. setChanged si clearChanged sunt declarate protected !
  684.  
  685. interfata Observer defineste metoda update, care are ca parametri obiectul subiect (care s-a modificat) si cea variabila de instanta din subiect s-a modificat (pret sau cantitate)
  686.  
  687. public class Item extends Observable (bananele din warehouse)
  688. defineste variabile de instanta nume, stocul si pretul
  689. constructorul si metodele get pentru fiecare instanta si metodele set
  690. metodele set sunt importante pentru ca acolo vine camionul, a venit camionul a descarcat o noua cantitate q pe care o folosim pt a actualiza stocul si apelam setChanged() adica spunem ca s-a modificat stocul si apelam notifyObservers cu noul stoc trimis ca argument.
  691.  
  692. delegare : clasa item contine o instanta Observable -> toate comportarile care vor fi legate de observable vor trebui delegate spre aceasta referinta. (inca nu e posibila o asemenea abordare)
  693. variabila state e controlata de metodele setChange si clearChanged care sunt PROTECTED (ele nu pot fi interogate de obiecte externe, pentru ca nu sunt publice)
  694.  
  695. solutia? definim o subclasa a lui observable definita observabletype si sa suprascriem metodele setChange si clearChange ca si public (este posibil pentru ca din design by contract, atunci cand subclasificam, accesul in sublcase trebuie sa fie mai permisiv decat accesul in superclase)
  696.  
  697. eroare de securitate, exista o metoda publica de a obtine observatorii (pt a adauga noi observatori) (cand cineva public poate sa adauge si sa stearga observatori)
  698.  
  699. se defineste un safeItem care extinde Item -> renuntam la returnarea getObservable si putem controla noi din interior cum se sterg (prezinta metodele addObserver si deleterObserver astfel nu sunt controlate de un program driver)
  700.  
  701. FRAMEWORKS
  702.  
  703. framework-ul ne da o solutie globala pentru un set de tipuri de probleme.
  704. framework-ul poate fi prevazut ca si o aplicatie semi-completa adica e dezvoltata pana de la un punct, si de la un punct incolo utilizatorul o customizeaza si o aplica.
  705.  
  706. cele mai populare frameworkuri sunt cele pt dezvoltarea aplicatiilor web
  707. pentru java -> spring
  708. pe pythong -> jungo
  709.  
  710. pt a usura munca de development se utilizeaza astfel de framework-uri in momentul in care nivelul de complexitate este mai mare. din perspectiva modului si a tehnicii de programare utilizate in cadrul frameworkului, orice framework se bazeaza pe IoC (responsabilitatea instantierii unui obiect va reveni frameworkului) el va fi cel ce instantieaza obiectul respectiv, instantierea se face cu DI. se folosesc functii de lookup pt a cauta dependente specifice care ar trebui sa fie injectate
  711.  
  712. ce contine un framework? deobicei va contine un set de clase (care sunt predefinite pt anumit functionalitati), un set de interfete. deobicei extindem clasele si le specializam si definim metodele de interfete. si un set de design pattern-uri care faciliteaza dezvoltarea de solutii generice si reutilizabile. utilizand tehnicile de programare utilizate pana acum, ceea ce facem noi in interiorul unui framework e sa transformam solutia generica intr-o solutie specifica domeniului pe care vrem noi sa il modelam. ca si principal scop e sa reutilizam cat mai mult cod si sa facilitam rapiditatea in dezvoltare a unor aplicatii. promoveaza reutilizarea codului si in acelasi timp este extensibil si se poate specializa foarte usor pentru tipul de aplicatie.
  713.  
  714. exemplu javaswing (poate fi vazuta ca un framework decat o librarie) un framework care ajuta crearea structurilor de interactiune cu frontend-ul unei aplicatii java si sa le administrezi.
  715. se ofera un set de interfete, un set de clase predefinite, ceea ce trebuie facut e sa extindem functionalitatea si sa o specializam pentru aplicatia noastra.
  716.  
  717. din perspectiva cantitatii de cod reutilizata, in cazul design pattern, cantitatea de cod e mai mica decat in cazul unui framework. nivelul de reutilizare e mai mic.
  718. framework-urile sunt specifice unui domeniu de aplicatie, pe cand design pattern-urile sunt specifice oricari tip de aplicatie (pentru o problema specifica)
  719.  
  720. diferenta intre framework si librarie
  721. in cazul in care utilizam o librarie este responsabilitatea programului sa instantieze librarie respectiva
  722. in cazul in care utilizam un framework se utilizeaza tehnica de IoC si in cazul asta e responsabilitatea frameoworkului sa instantieze un obiect in program si in cazul acesta se utilizeaza DI pentru a facilita acest lucru.
  723.  
  724. tehnici noi introduse in java o data cu java 8 (expresii lambda si interfete functionale)
  725.  
  726. un model de calcul devenit foarte popular in ultimul timp -> modelul de programare functional
  727. presupune dezvoltarea de functii si se bazeaza pe lambda calculus, si modalitate de implementare bazata pe trasarea starilor
  728. din perspectiva functiilor, ele nu sunt noi si programarea functionala exista de mult timp (Haskell)
  729. introducerea calculului paralel -> sunt multe calculatii care doresc sa proceseze cantitati mari de date, exista si capacitati hardware mult mai mari si pentru a putea fi exploatate e foarte de dorit ca programul facut sa poata sa rulez pe mai multe calculatoare/servere in paralel.
  730. programarea functionala are niste beneficii care faciliteaza parelelizarea rularii unui soft (atat la nivelul mai multor calculator, cat si mai multor core-uri)
  731. programele oop din perspectiva timpului de executie, sunt mai lente.
  732. au aparut asa numitele limbaje impure, care presupun amestec de concepte oop (cea mai mare parte e oop totusi), dar peste oop s-au introdus niste concepte si paradigme specifice programarii functionale, tocmai pentru a putea beneficia de avantajele aduse de programarea functionala, principalele caracteristici ale programarii functionale -> modalitatea de scriere a codului (declarativa)
  733.  
  734. model de scriere a codului declarativ -> pentru a controla codul, se bazeaza exclusiv pe functii si mai putin pe elemente specifice (if case switch break). principalul avantaj e dat de faptul ca fiind declarativ, cantitatea de cod este mult mai mica (codul e mult mai concis)
  735. promoveaza imutabilitatea -> a crea obiecte imutabile e o cerinta foarte importanta in momentul in care se dezvolta o aplicatie oop -> te scuteste de multe probleme si te ajuta sa pastrezi si sa localizezi cat mai bine impactul pe care bug-urile le pot avea in sistem. alta cerinta este evitarea side-effects (unul din principalele mod de a da seama daca o metoda e implementata corect este studiul efectelor secundare) (by default rolul unei metode e sa modifice starea unui obiect), dar in programarea functionala metodele definite sunt fara side-effecturi. singurele modificari care au loc sunt modificari care au loc in corpul metodei respective si asupra tipului de return, deci nu au efect asupra unei stari globale ale aplicatiei respective.
  736.  
  737. ofera suport pentru high-order functions (niste functii speciale care pot fi transmise ca si parametru in alte metode) (se transmite ca si parametru secvente si blocuri de cod) (principalul motiv este pentru a face codul cat mai concis, cu cat mai putine linii de cod) (probabilitatea de a aparea bug-uri devine mai mica si se usureaza intelegerea) (din perspectiva celor 2 stiluri de progamare, imperativ si declarativ)
  738.  
  739. in limbajul imperativ controlul (flow-ul de control) este dat de for, if, break, case, else (foarte multe tipuri de flow-uri de control), in cazul limbajului declarativ controlul se utilizeaza prin intermediul unor functii (contains). principalul avantaj al unei astfel de abordari este dat de faptul ca functiile respective pot sa proceseze colectiile intr-o maniera imutabila si mai mult, cei care furnizeaza functiile respective, pot sa se implementeze intr-o asa maniera a.i sa fie utilizate intr-o maniera paralelizata pe mai multe programe.
  740.  
  741. in buisness, va depinde de politica firmei daca promoveaza sau nu utilizarea obiectelor imutabile, sunt firme in care exista reguli speficice de calitatea codului. variabilele de clasa trebuie sa fie definite ca si final, nu trebuie sa avem metode de set definite si trebuie sa avem grija inclusiv la get pentru ca la get daca tipul de date returnat e un tip de date imutabil, folosind un get se poate modifica totusi starea obiectului prin deviatie (modifc starea unei variabile care-i imutabila). tipurile de date ale variabilelor sa fie pe cat posibil obiecte imutabile, daca nu sunt ar trebui ar trebui returnat copii in get (se face un shallow copy a variabilei respective care va fi returnata)
  742.  
  743. functiile de nivel inalt sunt functii care pot lua ca argumente alte functii ca si argument.
  744. expresie lambda -> fragment de cod anonim, avem o lista de parametrii, se foloseste ->
  745. o expresie lambda nu arunca exceptii, nu are nume, nu are clauze de return si nu se poate utiliza tipul generic intr-o expresie lambda.
  746.  
  747. interfete functionale -> o singura metoda abstracta si oricate alte metode statice, private si default.
  748. in programarea functionala nu este importanta ordinea executiilor statement-urilor.
  749.  
  750. intotdeauna blocul de cod se va mapa peste o intrefata functionala si avand in vedere ca interfata functionala respectiva are o singura metoda abstracta, fragmentul de cod va defini corpul metodei abstracte respective, deci lambda body va deveni corpul metodei abstracte din interfata functionala.
  751.  
  752. e foarte important ca administrarea expresiilor lambda sa se faca prin interfete functionala, pentru a sti compilatorul sa incerce sa mapeze body-ul peste metoda respecitva (avem nevoie de o metoda abstracta)
  753.  
  754. expresie explicita -> tipul de date a parametrilor e specificat in mod clar (int, String, orice tip de date)
  755. maniere implicita -> nu se specifica tipul de date, si atunci compilatorul va determina tipul de date in functie de contextul in care va fi apelat, in functie de parametrii de intrare a metode abstracte din interfata functionala peste care se va mapa. (comportamente diferite in contexte de mapare diferite)
  756.  
  757. in momentul in care avem expresii lambda in care nu am specificat tipul, pentru a infera tipul respectiv, compilatorul executa o secventa de pasi (pt a reusi sa dezambiguizeze codul expresiei lambda). din perspectiva modului de utilizare, pentru a o putea mapa pe o interfata functionala, intotdeauna o sa am un tip de interfata functionala T t = <LambdaExpression>
  758.  
  759. cum ajunge sa mapeze corpul undei metode abstracte? o secventa de 6 pasi. intotdeuna tipul T trebuie sa fie o interfata functionala. primul pas pe care il face compilatorul java e sa verifice ca tipul dat T este o interfata functionala. mai departe incearca sa mapeze input-ul sau parametri expresiei lambda peste header-ul metodei abstracte, se uita la metoda abstracta din interfata functionala T sa vada daca numarul de parametri se potriveste cu numarul de parametri din expresia lambda si daca expresia lambda ii explicita inseamna ca avem un map si fiind un map atunci va utiliza corpul expresiei lambda ca si corp a metodei abstracte respective. daca avem un match, verifica sa vada ca clauzele aruncate in context sunt compatibile cu clauzele potentiale definite in cadrul metodei abstracte si daca totul se potriveste, incluziv clauzele aruncate la run-time avem un match perfect si corpul expresiei lambda va deveni corpul metodei abstracte, deci expresia lambda va implementa intr-un fel interfata functionala, ii va da o implementare care se va utiliza ulterior.
  760.  
  761. behaviour parametrization -> comportamentul unei clase este modificat in functie de fragmentul de cod care este transmis ca si parametru intr-o metoda. in functie de fragmentul de cod si corpul expresiei lambda ce se transmit ca si parametru, comportamentul unei metode se va schimba. devine posibila din cauza faptului ca expresiile lambda sunt de fapt functii de nivel inalt, a caror comportament e preluat din programarea functionala.
  762.  
  763. din cauza faptului ca parametrii si corpurile lambda, nu au intotdeauna in mod explicit tipul de date definit, in mod clar ajungem la supraincarcarea metodelor si definirea de comportomante polimorfice. in cazul asta compilatorul trebui sa dezambiguizeze codul, sa incerce sa isi dea seama de tipul de date si tipul de metoda peste care se va mapa call-ul respectiv, metoda respectiva, pentru a-i putea da corp. ordinea de dezambiguizare : mai intai se uita la tipul de parametrii, daca e implicit clar se mapeaza nr de parametri si tipul de date exact, daca tipul de date nu e exact se poate utiliza un cast si ca o regula de a ajuta compilatorul sa dezambiguizeze informatia, se recomanda ca blocurile de cod lambda sa fie asignate inainte (explicit)
  764.  
  765. assignment-ul se poate face in functie de context :
  766. se poate face in contextul invocarii de metoda
  767. return context -> tipul de return sa fie inferat prin executia unei expresii lambda sau poate fi utilizat intr-un contest de cast, in care cast-ul sa fie cast-uit la o interfata functionala pe care se poate mapa.
  768.  
  769. interfetele funtionala penru un comparator : chiar daca interfetele lambda in corpul lor nu pot utiliza parametri generici, nu este nici o constrangere asupra interfetei si metodei abstracte. interfata si metoda abstracta pot sa utilizeze tipuri generice. tipul generic e un tip care ajuta compilatorul in a dezambiguiza anumite statement-uri si il ajuta mai ales sa faca verificari de tip la compile-time.
  770.  
  771. la run-time compilatorul va inlocui tipul generic cu tipul specific inferat, deci tipul generic are o importanta foarte mare la compile-time, de aceia la tehnica i se spune type eraser.
  772.  
  773. interfata functionala mapper<t> avem o metoda abstracta map si o metoda statica care face un mapToInt, metodele statice pot sa vina cu functionalitati. din perspectiva tipului de date asteptat in mapToInt avem o expresie generic, trebuie sa fie un supertip al tipului U, atunci compilatorul la runtime va verifica intotdeauna ca tipul de date trebuie sa fie supertip al lui U.
  774.  
  775. daca vreau sa definesc o expresie lambda care sa se mapeze si peste o interfata functionala si peste o interfata marker pot folosi intersectia de tipuri, folosind & expresia lambda se va mapa peste interfata functional si va beneficia si de proprietatea de marker adusa de interfata Serializable. fragmentul de cod generat va implementa ambele interfete.
  776.  
  777. platforma java a definit un set de interfete functionale. interfata Function care aplica o functie care va veni printr-o expresie lambda, o va aplica asupra unui tip T si va returna un raspuns. BiFunction la fel numai ca va aplica functia peste 2 parametri.
  778. Predicate evalueaza un predicat pe care il primeste ca si input.
  779. Consumer consuma un tip de date si nu returneaza niciun rezultat -> utilizat cand vreau sa utilziez expresii lambda care fac print de informatii
  780. Supplier-ul returneazaza o valoarea -> procesarea unui informatii si returnarea unei valori.
  781.  
  782. interfata function.
  783.  
  784. are 3 metode in ea (o metoda abstracta, metoda de apply (aplica functia)) si mai multe metode default care ajuta la implementarea metode apply care furnizeaza functionalitati suplimentare, cum ar fi compose (compunerea functiilor). andThen permite aplicarea functiilor succesive. super reprezinta intotdeauna un supertip a lui t iar extends un subtip a lui t
  785. <? super T> -> SUPERTIP a lui t
  786. <? extends T> -> SUBTIP a lui t
  787.  
  788. square.andThen(addOne) si avem 5 -> 5 * 5 + 1 -> 26
  789. squeare.compose(addOne) si avem 5 -> (5 + 1)^2 -> 36
  790.  
  791. pe langa functia generica function exista si functii nongenerice (functii definite pentru fiecare tip de data in parte)
  792.  
  793. interfata predicate
  794.  
  795. verifica valoarea de adevar a unui predicat care va fi definit printr-o expresie lambda. exista metode care ne permit sa facem and / or / isEqual.
  796.  
  797. interfata Consumer
  798.  
  799. nu returneaza nicio valoare -> se utilizeaza pentru expresii lambda care consuma informatii, dar nu returneaza niciun tip (pentru imprementarea de print-uri).
  800.  
  801. interfata Supplier
  802.  
  803. implementeaza un get, rolul ei e sa returneze o valoare si se foloseste de fiecare data cand o variablia trebuie returnata, pentru a implementa un salut. poate fi implementata in fiecare caz in care nu avem niciun parametru de intrare pe expresia lambda.
  804.  
  805. method reference -> se utilizeaza folosind doua puncte si are rolul de a apela o metoda, nu-i un tip nou de date si nu e un pointer la o functie; e doar o modalitate de a explica o metoda care sa se execute. vrem sa se execute metoda length pe un string. vreau sa apelez metoda length a clase string. scrierea e mult ma iconcisa si mai usor de inteles pt a specifica tipul de date folosind method reference exista mai mutle modalitati.
  806.  
  807. stream
  808.  
  809. secvența elementelor de date
  810. operațiunile de flux pot fi executate secvențial sau în paralel
  811. Stream<T> -> operații pe secvența de elemente care susțin operații de agregare secvențiale și paralele
  812. (collect, count, empty, filter, forEach, iterate, generate, limit, max, min, of, reduce, skip, sorted)
  813. Collector<T,A,R> -> operație de reducție mutabilă (acumulează elementele de intrare T într-un container mutabil A; R este tipul rezultat al operației de reducere.
  814. stream-urile nu sunt colectii
  815. o colecție deține toate elementele în memorie
  816. doar o parte a stream-ului este prezenta in memorie (elementele lui sunt calculate cand este nevoie de ele)
  817. streamurile consuma date din collecti
  818. fluxurile se concentrează pe calcule agregate pe elemente de date dintr-o sursă de date care ar putea fi colectate
  819. colecțiile necesită o iterație explicită asupra valorilor sale
  820. cu fluxuri, iterația este implicită în operațiuni (fluxurile sunt iteratoare inteligente peste colecții)
  821. stream-urile permit scrierea unui cod care este :
  822. declarativ (concis si sigur)
  823. flexibil
  824. paralelizabil (performanta mare)
  825. pipelined -> multe operații de flux returnează un flux, permițând astfel operațiunile să fie înlănțuite în pipeline-uri mari.
  826. un pipeline de operatii poate fi vazut ca o interogare a unei baze de date pe o sursa de date
  827.  
  828. fluxurile nu au stocare
  829. un flux își trage elementele dintr-o sursă de date care poate fi o colecție sau o funcție care generează date
  830.  
  831. ex : calculul sumei patratelor numerelor impare
  832. external iteration (iterator object) -> while(it.hasNext())
  833. external iteration (for each statement) -> for
  834. iteratie externa -> clientul programului scoate valori din colecție și le procesează unul câte unul pentru a obține rezultatul
  835. produs prin codul de execuție secvențial care poate fi executat doar de un singur thread.
  836.  
  837. iteratia interna -> foloseste fluxuri (streamuri)
  838. int sumSqOdd = numbers.stream().filter.map.reduce
  839.  
  840. tipuri de operatii cu stream-uri / fluxuri
  841.  
  842. operatii intermediare (sau lenese)
  843. preia elemente dintr-un flux de intrare și transformă elementele pentru a produce un flux de ieșire
  844.  
  845. operatii intermediare (sau dornice) ia elementele dintr-un flox si produce rezultatul
  846.  
  847. fluxul este în mod leneș până când apelați o operație de terminal pe acesta
  848.  
  849. operații intermediare
  850. au alt stream ca tip returnat
  851. permit operatiilor sa fie conectate intr-o interogare
  852. operațiunile intermediare nu efectuează nicio prelucrare până când nu este invocată o operație de terminal pe fluxul pipeline , sunt operații leneșe
  853. exemple de operatii intermediare (filter, map, distinct, sorted, peek, limit, etc)
  854.  
  855. operatii terminale
  856. operatiile terminale pe un flux produc o valoare ce nu este flux (o colectie, un tip primitiv sau nicio valoare)
  857. sunt precedate de operatii intermediare
  858. exemplu : forEach, collect, count, toList, toArray, min, max, etc.)
  859.  
  860. operatia terminala forEach
  861. execută o acțiune asupra fiecărui element al unui flux considerat consumator
  862.  
  863. operatiile terminale sum max min average etc.
  864. citesc valorile dintr-o colecție și determina numărul total de caractere
  865.  
  866. operatia terminala - reduce
  867. utilizat atunci când este necesar pentru a reduce un flux la o singură valoare, cum ar fi calculul produsului sumei, minimului etc (de ex suma tuturor valorilor ar fi .reduce(0,(c1,c2) -> c1 + c2);
  868.  
  869. operatia terminala - collect
  870.  
  871. caz special de operare de reducere numit reducere mutabilă
  872. returnează un container cu rezultate mutabile, cum ar fi o listă, un set sau o mapare, așa cum este indicat de colectorul furnizat.
  873. interfata Collector <T,A,R>
  874.  
  875. T - tipul de element care este procesat de flux și urmează să fie colectat
  876. A - tipul containerului rezultat rezultat care continuă să obțină elemente (de tip T) adăugate pe parcursul procesului de colectare
  877. R - tipul containerului rezultat sau colecția care este returnată înapoi ca o ieșire finală de către colector
  878.  
  879. membrii interfetei Collector sunt folositi de 4 componente
  880. Supplier -> furnizează instanță sau instanțe goale de tip A pentru a începe acumularea de elemente
  881. acumulatorul folosește o instanță a lui A pentru a colecta T
  882. Combiner-ul -> combină două rezultate parțiale acumulate de tip A pentru a produce o instanță combinată de A
  883. Finisher-ul -> mapeazaz A in R folosind o functie de mapare.
  884.  
  885. Intrebari
  886.  
  887. When an array of boolean elements is created, its elements are
  888. assigned to the default value false
  889.  
  890. Which statement about (static) variables is correct
  891. there is only one copy of each class variable that is shared by all instances of the class
  892. a class variable does not need an object instance to use it without
  893.  
  894. A method that is associated to an individual object is called instance method
  895.  
  896. Consider the following declarations :
  897. Interface I {}
  898. Class B {}
  899. Class D extends B implements I
  900. which of the following object instantiations are correct?
  901. I o2 = new D();
  902. B o5 = new D();
  903.  
  904. What is true about a class constructor?
  905. It may be overloaded
  906. It is called with the new operator
  907.  
  908. Which statement is true about the class shown below?
  909. public class TestPT1()
  910. { public void m1() {}
  911. public static void main(String args[])
  912. { m1(); }
  913. }
  914. It will not compile because m1() is not static
  915.  
  916. Which statement is true about the order of methods in a class
  917. The methods can be listed in any order
  918.  
  919. What is the output of the program below
  920. interface A {}
  921. class C{}
  922. class D extends C{}
  923. class B extends D implements A
  924.  
  925. class TestPT2 {
  926. public static void main(String args[])
  927. {
  928. B b = new B();
  929. if(b instanceof A) System.out.println("b is instance of A");
  930. if(b instanceof C) System.out.println("b is instance of C");
  931. }
  932. b is instance of A b is instance of C
  933.  
  934. Point[] p = new Point[10]
  935. Which of the statements is most accurate?
  936. p contains a reference to an array of size 10 and each array element can store a reference to a Point object.
  937.  
  938. Consider the concrete classes A and B and a method mA partially defined as below :
  939.  
  940. public class A {
  941. public mA(B b) { }
  942. }
  943.  
  944. What is passed as parameter when calling the method mA ?
  945. A reference to an object of type B
  946.  
  947. Person sally = new Person()
  948. sally nu e o persoana, e o referinta la un obiect de tip Person(), ar fi un numar (hexadecimal care arata unde e stocata persoana in memorie) (un middleman care stie unde este localizat obiectul in memorie)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement