Dizajniranje programa

Kada dizajniramo mali računarski program ili velike softverske sisteme mi obično imamo mentalni model problema koji pokušavamo da rešimo. Kako mi smišljamo mentalni model softverskog sistema?

Programske paradigme nude više različitih metoda dizajniranja i osmišljavanja softverskih sistema.

Paradigma se može posmatrati kao mentalni model ili kao okruženje za dizajniranje i opisivanje strukture softverskog sistema.
Model nam pomaže da osmislimo i formulišemo rešenja.
Mentalni model paradigme možemo koristiti nezavisno od izabranog programskog jezika za implementaciju.

Međutim, kada izabrani jezik obezbeđuje konstrukcije i mehanizme koji su slični onima koji se nalaze u paradigmi, tada će implementacija biti neposrednija. Obično, više jezika pripada nekoj paradigmi. Iz tog razloga, programska paradigma se takođe smatra klasom jezika.

Jezik ne mora da pripada samo jednoj paradigmi. Često, jezici imaju svojstva ili karakteristike iz više paradigmi. Hibridni jezici, takvi kao C/C++, kombinuju karakteristike dve ili više paradigmi. C obuhvata karakteristike iz imperativne i proceduralne paradigme, dok jezik C++ obuhvata objektno-orijentisane paradigme.

Imperativna paradigma

Imperativna paradigma je karakteristična po apstraktnom modelu računara sa velikim memorijskim skladištem.
To je klasičan von Neumannov model arhitekture računara.
Izračunavanja, koja se sastoje od sekvence komandi su smeštena kao kodiranja unutar memorijskog skladišta.
Komande omogućuju mašini da pronađe rešenja koristeći dodeljivanja koja modifikuju memorijsko skladište, promenljive da očitava memoriju, aritmetiku i logiku da izračuna izraze, i uslovno grananje da upravlja tokom izvršavanja.
Asemblerski jezici i BASIC su primeri jezika ove paradigme.

Proceduralna paradigma

Proceduralna paradigma obuhvata imperativnu paradigmu, ali je proširuje sa mehanizmom apstrakcije za generalizovanje komandi i izraza u procedure (funkcije).
Parametri, koji su u stvari pseudonimi za deo memorije, takođe su uvedeni ovom paradigmom.
Ostala svojstva su iteracija, rekurzija i selekcija.
Jezici C, FORTRAN i Pascal predstavljaju jezike u ovoj paradigmi.

Dizajniranje sistema u proceduralnoj paradigmi obuhvata modelovanje sistema kao skupa algoritama (procedura) na skupu vrednosti podataka.
Vrednosti podatka predstavljaju adrese memorije. Svaka procedura interaguje sa memorijom direktno.
Proceduralni jezici predstavljaju važnu evoluciju u odnosu na imperativne jezike zbog toga što obezbeđuju sposobnost i snagu von Neumannove arhitekture nezavisno od fundamentalnih detalja mašine.
Proceduralna paradigma je bila prva paradigma koja je uvela pojam apstrakcije u dizajniranje programa.
Cilj apstrakcije u programiranju je da se odvoji ponašanje od implementacije.
Procedure su oblik apstrakcije. Procedura obavlja neki zadatak ili funkciju. Drugi delovi programa pozivaju proceduru, znajući da će ona obaviti zadatak korektno i efikasno, ali ne znajući tačno kako je procedura implementirana.
Procedure su vrlo brzo prepoznate kao snažan mehanizam i utrle su put za dalje oblike apstrakcije. Jedan od nedostataka proceduralne apstrakcije je njena labava veza između procedure i podataka kojima manipuliše, tj svi jezici su bili algoritamski orijentisani. Algoritamski orijentisan jezik su imali više nedostataka, medju kojima se ističu kompatibilnost, kontinuitet i višestruka upotreba. Dizajneri jezika razvili su nove oblike apstrakcije kako bi ponudili bolje mehanizme apstrakcije za podatke.

Proceduralna paradigma sa apstrakcijom tipa podataka

Apstrakcija podataka (engl. data abstraction) se odnosi na odvajanje ponašanja podataka od njihove predstave ili implementacije, tj deskriptivnih elemenata od njihovim aktivnih elemenata.
Na primer, stek sadrži operacije Push, Pop i IsEmpty.
Stek stavlja na raspolaganje korisnicima ove operacije ali ne otkriva kako je stek stvarno implementiran. Stek bi mogao da se implementira pomoću niza ili liste. Korisnike steka ne interesuje kako je stek implementiran, za njih je bitno da on navedene operacije obavlja korektno i efikasno.
Pošto je osnovna implementacija podatka sakrivena od korisnika, implementacija može lako da se promeni bez uticaja na programe koji ga koriste.

Kada dizajniramo algoritme često nam je potrebno da koristimo konkretan tip podatka da izvršimo operacije algoritma. Dizajniranje algoritma je lakše ako jednostavno specificiramo tipove podataka i promenljive, ne vodeći računa o tome kako je stvarni tip podatka implementiran. Tip podatka opisujemo preko njegovih svojstava i operacija i podrazumevamo da bez obzira koja implementacija je izabrana, operacije će raditi korektno i efikasno.
Tipovi definisani na ovaj način nazivaju se APSTRAKTNI TIPOVI PODATAKA (ABSTRACT DATA TYPES - ADTs).

Na primer, pretpostavimo da razvijamo simulacioni sistem za proučavanje eko-sistema. Potrebna nam je struktura da pamti interesantne događaje i sortira ih prema prioritetu. Potrebno nam je da možemo da ubacujemo događaje u strukturu podataka i da ih uklanjamo prema prioritetu.
Ovaj konkretni apstraktni tip podataka nazvaćemo red prioriteta (engl. priority queue).
Za potrebe dizajniranja našeg simulacionog algoritma ne moramo da specificiramo tipove stavki u redu, niti da specificiramo tipove podataka prioriteta. Potrebno je samo da pretpostavimo da će prioriteti biti uređeni.

Upotreba apstraktnih tipova podataka čini dizajniranje algoritma opštijim i omogućava nam da se koncentrišemo na sam algoritam bez zalaženja u detalje implementacije. Pošto je algoritam dizajniran, biće potrebno implementirati stvarne tipove podataka, zajedno sa algoritmima.
Nešto kasnije, proceduralni jezici su prošireni da podrže definicije novih tipova podataka i obezbede sredstva za apstrakciju podataka. Jezici CLU, Ada i Modula-2 su primeri jezika koji to obezbeđuju.

Objektno orijentisana paradigma

Objektno-orijentisana paradigma zadržava mnogo od karakteristika proceduralne paradigme, pošto su procedure još uvek primarni oblik za komponovanje izračunavanja.
Međutim, umesto da operišu nad apstraktnim vrednostima, programi objektno-orijentisane paradigme operišu nad objektima.
Objekat je vrlo sličan apstraktnom tipu podatka i sadrži podatke kao i procedure.

Postoje tri primarne karakteristike objektno-orijentisane paradigme.
Već smo opisali prvu, INKAPSULACIJU (engl. ENCAPSULATION), mehanizam za primenu apstrakcije podatka.

Druga karakteristika je NASLEĐIVANJE (engl. INHERITANCE). Nasleđivanje dopušta da novi objekti budu kreirani iz postojećih, opštijih objekata i samim tim rešava problem kontinuiteta koji se javio kod kompozitnih, proceduralnih i strukturnih programskih jezika.
Novi objekat postaje specijalizovana verzija opšteg objekta. Novi objekti treba samo da obezbede metode ili podatke koji se razlikuju zbog specijalizacije. Kada se jedan objekat kreira (ili izvede) iz drugog objekta, kaže se da nasleđuje metode i podatke objekta roditelja, i obuhvata svaku novu predstavu i dodate nove ili prerađene metode.

Treća karakteristika objektno-orijentisanog programiranja je POLIMORFIZAM (engl. POLYMORPHISM) tj. konteksno zavisno ponašanje. Polimorfizam dopušta više različitih tipova objekata da obave istu operaciju odgovarajući na istu poruku.
Na primer, imamo kolekciju objekata koji mogu da obave operaciju sortiranja. Međutim, mi ne znamo koji tipovi objekata će biti kreirani sve do trenutka izvršavanja. Objektno-orijentisani jezici sadrže mehanizme koji osiguravaju da će svaka poruka sortiranja biti poslata pravom objektu.

Inkapsulacija, nasleđivanje i polimorfizam se smatraju fundamentalnim karakteristikama objektno-orijentisanog programiranja i svi objektno-orijentisani jezici svojim tehnikama moraju da obezbede te karakteristike na neki način. Svakako nije iznenađenje da jezici iz ove grupacije podržavaju te karakteristike na veoma različite načine. Smalltalk, C++, Objective-C i Lisp (sa CLOS-om - Common Lisp Object System) su primeri objektno-orijentisanih jezika i svaki od njih obezbeđuje tehnike za enkapsulaciju, nasleđivanje i polimorfizam.

Konstruisanje objektno-orijentisanog programa obuhvata određivanje objekata koji su potrebni za rešavanje problema.
Zatim se objekti koriste da se konstruišu izračunavanja koja definišu ponašanje softverskog sistema. Prosleđivanje poruka (engl. message passing) je fundamentalni mehanizam interakcije između objekata. Poruke (od drugih objekata ili programa) se šalju objektima da ih informišu da obave neku od svojih operacija.

Objekti su odgovorni za održavanje stanja svojih podataka. Samo objekat može da modifikuje svoje interne podatke. Sami objekti mogu biti implementirani preko drugih pod-objekata. Implementiranje objekta obuhvata rekurzivni proces razlaganja u pod-objekte sve dok se ne dođe do nekog nivoa objekata i metoda definisanih nad njima koji su primitivni. U toj tački, metodi i podaci sastoje se od elemenata koji se mogu implementirati pomoću osnovnih konstrukcija koje obezbeđuje programski jezik.

Jedan od najvažnijih aspekata objektno-orijentisane paradigme je kako ona menja naš način razmišljanja o softverskim sistemima. Polazi se od stanovišta da se sistemi sastoje od individualnih entiteta i klasa entiteta koji su odgovorni za izvršavanje sopstvenih operacija.
Svaki objekat je zamišljen i implementiran kao samostalan. Takav model olakšava dizajniranje softvera (i kasniju implementaciju) zato što su objekti često konceptualni model entiteta iz realnog sveta.

Dizajniranje sistema pomoću objektno-orijentisane paradigme kao rezultat daje softverske sisteme koji se ponašaju slično svojim pandanima iz realnosti.

Autor: Dragan Marković & rand0m

Unless otherwise stated, the content of this page is licensed under GNU Free Documentation License.