680 likes | 906 Views
Vzorci načrtovanja (Design patterns). O čem bomo govorili. Kaj so načrtovalski vzorci ( design pattern ) ? Zakaj jih potrebujemo ? Kako jih lahko uporabimo ? Zgled : “ factory pattern ”. Frameworks. Patterns. UML Diagrams. Use case description. Kaj so vzorci ?.
E N D
Vzorci načrtovanja (Design patterns)
O čem bomo govorili • Kaj so načrtovalski vzorci (design pattern)? • Zakaj jih potrebujemo? • Kako jih lahko uporabimo? • Zgled: “factory pattern” Frameworks Patterns UML Diagrams Use case description
Kaj so vzorci? • Vzorci opisujejo pogoste probleme, opisujejo tudi bistvo rešitve. Na ta način lahko rešitev ponovno uporabimo na več načinov. • Še ena definicija : “opisi objektov in razredov, ki komunicirajo in ki so prilagojeni reševanju splošnega načrtovalskega problema v nekem posebnem kontekstu”.
Vzorci v realnem življenju • Vzemimo primer, pojem “vrat” je zelo splošen: Povezuje dve stvari, Lahko jih odpremo ali zapremo. Hišna vrata in vodna pipa so “vrata”. Imajo nekaj skupnega: • Dve strani • Nekaj (pretok), kar lahko teče. • Hitrost pretoka. • Če razumemo te, skupne stvari, lahko gradimo boljša “vrata”
Zakaj jih rabimo v programskem inženirstvu? • Sporočajo probleme in njihove rešitve, do katerih so skozi vrsto projektov prišli izkušeni razvijalci. • Zapisani so na abstrakten način in jih zato lahko uporabimo v različnih kontekstih
Interna uporaba v aplikacijah • Prednost je v zmožnostih vzdrževanja in razširjanja. • Interna ponovna uporaba pomeni za dano aplikacijo zmanjšanje načrtovanja in implementacije • Načrtovalski vzorci, ki zmanjšujejo sklapljanje in povečujejo sodelovanje, lahko povečujejo interno ponovno uporabljivost.
Košarice orodij -Toolkits • To so knjižnice vnaprej definiranih, med seboj povezanih in ponovno uporabljivih razredov. • Aplikacije imajo take “košarice” vgrajene (na primer C++ I/O stream library). • Aplikaciji ne vsiljujejo načrta, odvračajo pa programerje od ponovnega kodiranja funkcionalnosti. • Njihov razvoj je težji od razvoja aplikacij, saj morajo predvideti delovanje v različnih aplikacijah.
Ogrodja (frameworks) • Framework: Skupina sodelujočih razredov, ki omogočajo ponovno uporabljiv razvoj za določeno vrsto programov. • Ogrodja so prilagojena posamezni aplikaciji tako, da iz abstraktnih razredov tvorimo aplikaciji specifične podrazrede. • Ogrodja diktirajo arhitekturo aplikacije • Bolj poudarjajo ponovno uporabo razvoja in ne ponovno uporabo kode. • Implementirati jih je zelo težko.
Razlika med vzorci in ogrodji • Načrtovalski vzorci (design patterns) so bolj abstraktni od ogrodij (frameworks) • Načrtovalski vzorci so manjši gradniki. • Načrtovalski vzorci so manj specializirani od ogrodij.
Inverzija nadzora • Ponovna uporaba (v ogrodjih) povzroči inverzijo nadzora med aplikacijo in programsko opremo, na kateri ta temelji. • Pri košarici (toolkit) pišemo kodo aplikacije in kličemo košarico. • Z ogrodjem pa ponovno uporabimo glavno telo in pišemo kodo, ki je klicana iz tega telesa.
Mislimo na to... • Kdaj bomo uporabili aplikacijo, kdaj košarico (toolkit) in kdaj ogrodje (framework)? • Če moramo v kratkem razviti manjšo spletno lokacijo in smo neizkušeni, kateri pristop je boljši?
Primer: vzorecObserver • Primer obdelave besedil • Kaj se dogaja: • Kontrolerobvesti model, da naj vključi vtipkano besedilo • Model opozori vse poglede (views) o spremembi v modelu • Pogledi se osvežijo • Med osvežitvijo vsak pogled vpraša model, kakšno je trenutno besedilo.
Vzorec Observer (2) • Kontekst • Nek objekt (“subjekt”) je izvor dogodkov (“moji podatki so se spremenili”) • Eden ali več objektov -opazovalcev (“observers”) želi vedeti, kdaj pride do nekega dogodka. • Rešitev • Definiramo vmesnik za tip observer. Razredi opazovalca morajo implementirati ta tip vmesnika • Subjekt vzdržuje kolekcijo objektov observer • Razred subjekta nudi metode za navezovanje opazovalcev • Ko pride do dogodka, subjekt opozori vse opazovalce
Primer: vzorec Abstract factory • Nudi vmesnik za tvorbo družin povezanih oziroma odvisnih objektov,ne da bi pri tem specificirali njihove konkretne razrede • Motivacija: Zgledna “košarica orodij” za vmesnike, ki podpira različne standarde “look and feel”. • Drugi primeri: Web Services Description Language (WSDL) in OACS contract services
Nekateri arhitekturni vzorci • Facade: Dinamična informacija na spletni strani je pogosto sestavljena iz množice vsebinskih objektov. • Templated page. Definira eno šablonsko stran, skozi katero morajo iti vse izhodne strani, preden so servisirane. • Thin Client. Vsa poslovna logika se izvaja na strežniku. • Thick web client. Tenek odjemalec je razširjen s skripti na strani odjemalca in prilagojenimi objekti (na primer appleti in Flash)
Zakaj vzorci? • Učenje razvoja programov je težavno • Jeziki in ogrodja so zelo kompleksni • Imeti moramo boljši način komunikacije • Vzorci in jezik vzorcev (“pattern languages”) dajejo delni odgovor
Kaj je načrtovalski vzorec? • Rešitev načrtovalskega problema, ki pogosto nastopa • Pomaga tvorbo fleksibilnega in ponovno uporabljivega načrta • Ima širši pomen od posameznega razreda ali algoritma • Opisuje okoliščine, pri katerih lahko vzorec uporabimo • Opisuje posledice in “ceno” (trade-offs) uporabe vzorca v sklopu nekega večjega načrtovanja • Je jezikovno neodvisen
Od kod prihajajo vzorci • Vzorci prihajajo iz arhitekture • A Pattern Language [Alexander77] • Jezik vzorcev (Pattern Language) opisuje • Pogosti arhitekturni motivi • Kako z vsem skupaj ustvariti bivalno okolje
Arhitekturni in načrtovalski vzorci • Arhitekturni vzorcinaslavljajo probleme • Porazdeljene funkcionalnosti in razdelitve sistema • Protokolov in vmesnikov • Skalabilnosti, zanesljivosti, varnosti • Delovanja in vpliva “porazdeljenega sistema” • Načrtovalski vzorcinaslavljajo probleme • Vzdrževalnosti, ponovne uporabljivosti kode, ogrodij (frameworks) • Abstrakcije in skrivanja algoritmov • Vpliva “objektno usmerjenega jezika”
Zakaj uporabiti načrtovalske vzorce? • Preskušene rešitve pogostih OO problemov • Prenos izkušenj začetnikom • Skupen slovar načrtovalcev • Dokumantacija za obstoječa ogrodja • Ko to osvojimo, postanejo dobre tehnike načrtovanja naravne • Pogosto jih kombiniramo in ustvarjamo bolj sofisticirane načrte
Katere probleme rešujemo z načrtovalskimi vzorci? • Dobri načrti se sprememb ne bojijo • Uporabljene tehnologije se spreminjajo • Poslovni cilji se spreminjajo • Pričakovanja uporabnikov se spreminjajo • OOP nudi orodja za spopad s spremembami: • Enkapsulacija • Dedovanje • Polimorfizem • Imeti orodja = dobro. Jih dobro uporabljati = boljše.
Primer problema • In the beginning, you get the following requirement: The regional sales entry system must send data, in batches, to the accounting package (Microsoft Great Plains Accounts Receivable). • You create the OrderCollector class.
In sedaj sprememba zahtevkov • Good news: our departmental application is being picked up by the manufacturing division in Florida. • Bad news: they use Solomon for their accounting package. Fix the code to use Solomon as well as Microsoft Great Plains. • The interaction is quite different. You have to change the code that calls the accounting interface.
Problem z rešitvijo • The code to call the Microsoft Great Plains solution is similar to the code that calls the Solomon solution. • Business rules specific to the task of “send something to accounting” are mixed in with business rules for “send data to the specific package.” • Therefore: if another accounting package comes in, say Oracle, you’d have to do it again. • The interfaces are fairly different… inheritance doesn’t appear to help.
Uporabimo vzorec Adapter • Adapter “pretvori vmesnik razreda v nek drug vmesnik, ki ga odemalec pričakuje.” • V nasednjem primeru uporabljamo variacijo vzorca Adaptee,ki mu pravimo “pluggable adapter using abstract operations” • Vzorec izgleda tako:
Boljša zaradi ... • Poslovna pravila so ločenaod tehničnih pravil. Zato jih lažje beremo in preskušamo. • Poslovna pravila implementiramo enkrat in samo enkrat. Zato jih lažje najdemo in posodabljamo. • Če dodamo nov sistem obračunavanja, moramo sprogramirati le nov adapter. Poslovna koda že obstaja in jo (običajno) lahko ponovno uporabimo.
In kaj smo s tem pridobili? To bi vendar lahko naredil s programsko šablono (code template)! To sem že prej sam, delal! Zakaj bi temu rekli vzorec? Moč načrtovalskih vzorcev ni le v šablonah in delčkih ponovno uporabljive kode… uvajajo nov način razmišljanja o objektih. Vzorci so primeri, ki nas vodijo v ta preskok.
Nekaj vprašanj • Ali so objekti le “podatki z metodami?” • Ali pomeni enkapsulacija isto kot skrivanje podatkov? • Ali dedovanje najbolje uporabljamo za tvorbo “specializiranih” verzij razreda?
Drug način razmišljanja • Enkapsulacija = skrivanje vsega… ne le podatkov • Objekti kot “realizirana množica odgovornosti” • Abstraktni razredi, ki definirajo “skupne” zmožnosti objekta, z dedovanjem, s katerim specificiramo variacije.
Drug način programiranja • Usmerimo se v to, kaj naj bi objekti naredili, ne pa le, kako jih implementirati. • Razmislimo, kaj je v načrtu spremenljivega... nato pa to skrijmo. • Postavimo plasti med stvari, ki se spreminjajo neodvisno. • Načrtovalski vzorci = uporabljene najboljše izkušnje iz načrtovanja programov • Preskušene metode za skrivanje stvari, ne le podatkov. • “Commonality vs. Variability” je bistvo načrtovalskih vzorcev
Kaj pridobimo z načrtovalskimi vzorci • Vzpostavimo besednjak • Ekipe lahko komunicirajo na višjem nivoju • Zaradi ponovne uporabe tehnične rešitve se lahko bolj usmerimo v poslovni problem • Dokumentacijo bomo lažje razumeli • Izboljšamo naše kodiranje • Lažje bo vzdrževanje: manj povezovanja, večja kohezija • Osvojili bomo pojme “commonality vs. variability” • Poveča se naša produktivnost • Zakaj bi spet izumljali kolo?
Trenutna uporaba vzorcev Razvijalci Katalog vzorcev (večinoma s primeri kode Izvorna koda
Generiranje kode, temelječe na vzorcih • Dober vzorec naj bi imel najmanj tri znane dobre implementacije, kar kaže, da se ga da uporabiti na več načinov • Ta relacija ena na več vzpodbuja uporabo vzorcev za generiranje kode
Strukturni vzorci (Structural Patterns) • Nek podsistem vsebuje • Objekt vmesnik (interface) • Množico objektov aplikacijske domene, ki modelirajo resnične entitete ali obstoječe sisteme • Enega ali več nadzornih objektov • Realizacija objekta vmesnik : Facade • Nudi vmesnik do podsistema • Vmesnik do obstoječega sistema: Adapter ali Bridge • Nudi vmesnik do obstoječega sistema
VzorecFaçade • Facade nudi poenoten vmesnik do skupine razredov v podsistemu • Abstrahira bistvo podsistema in skrije podrobnosti implementacije in kompleksne povezave med komponentami • Primeri: vmesnik za povezovanje z več podatkovnimi bazami (JDBC) ali omrežnimi strežniki (sockets/RMI) in skrivanje podrobnosti povezovanja
Vzorec Façade Za povezovanje s podatkovno bazo:
Tvorba razredov Façade • Najprej naložimo gonilnik podatkovne baze try{Class.forName(driver);} //load the Bridge driver catch (Exception e) {System.out.println(e.getMessage());} • Se povežemo s podatkovno bazo try {con = DriverManager.getConnection(url); dma =con.getMetaData(); //get the meta data } catch (Exception e) {System.out.println(e.getMessage());} • Potrebujemo seznam imen tabel, z metodo getTabledobimo objekt ResultSet. • Seznam imen dobimo z iteracijo preko tega objekta
Tvorba razredov Façade (nadaljevanje). public String[] getTableNames() { String[] tbnames = null; Vector tname = new Vector(); //add the table names to a Vector //since we don't know how many there are try { results = new resultSet(dma.getTables(catalog, null, "%", types)); } catch (Exception e) {System.out.println(e);} while (results.hasMoreElements()) tname.addElement(results.getColumnValue("TABLE_NAME")); //copy the table names into a String array tbnames = new String[tname.size()]; for (int i=0; i< tname.size(); i++) tbnames[i] = (String)tname.elementAt(i); return tbnames; }
Adapter • Namen • Pretvorba vmesnika nekega razreda v drug vmesnik, kakršnega pričakujejo odjemalci • Znan tudi kot Wrapper • Motivacija • Potencialno ponovno uporabljiv razred nima ustreznega vmesnika, ki ga zahteva določeno področje uporabe • Uporabnost. Uporabimo, ko… • hočemo uporabiti razred, njegov vmesnik pa nam ne ustreza • hočemo narediti ponovno uporabljiv razred , ki sodeluje z nepredvidenimi razredi
Adapter • Struktura • uporablja večkratno dedovanje (ali njegov ekvivalent) za prilagoditev enega vmesnika na drugega. • Udeleženci • Cilj (target), Odjemalec (Client), Prilagojenec (Adaptee), Prilagoditelj (Adapter) • To je predstavitev razreda adapter – imamo lahko tudi objekt adapter – uporabimo delegiranje namesto dedovanja
Adapter – Primer kode • Pomislimo na urejevalnik, ki podpira like (shapes) in besedilo(text) • Text in Shape sta bila načrtovana neodvisno - vendar si želimo, da bi ju enako uporabljali • na primer. • Shape uporablja očrtan pravokotnik (Bounding Box), • Text pa uporablja izhodišče (origin), višino (height) in širino (width)
Adapter – Primer kode (2) • Adapter za združevanje vmesnika uporablja dedovanje in implementacijo. • V našem primeru prihaja vmesnik od “Shape”, implementacija pa od “Text”. • TextShape se obnaša tako kot objekt Shape in kot objekt Text.
Adapter - posledice • Class Adapter: • Prilagodi prilagojenca (adaptee) cilju tako, da posreduje konkretnemu razredu. Tako ne moremo prilagoditi razreda ali njegovih podrazredov • Adapter lahko prekrije določeno obnašanje prilagojenca • Uvede le en objekt in nobenih dodatnih kazalcev • Object Adapter: • Dopusti, da adapter sodeluje z več prilagojenci • Obnašanje prilagojencev težje prekrijemo
VzorecBridge • Podoben vzorcu Adapter: uporabimo razred za pretvorbo enega vmesnika v drugega • Uporabljamo kot “up-front” v načrtovanju in tako omogočimo neodvisno spreminjanje abstrakcij in implementacij • Vzorce “Bridge” uporabljamo če v času analize ali načrtovanja še ne popolnoma poznamo celotne množice.
VzorecProxy • Namen • Ponudi nadomestek za drug objekt. Ta nadomestek nadzoruje dostop do njega • Poznan tudi kot • Surrogate • Uporaba: • Za skrivanje kompleksnosti omreženega objekta • Pomoč pri nalaganju objekta s počasnim dostopom • Preverjanje dovoljenj za dostop do objekta in validacija njegove uporabe • So primeri, ko odjemalec ne more neposredno naslavljati nekega objekta, pa vseeno želi z njim interaktirati • Objekt “proxy” lahko deluje kot posrednik med odjemalcem in ciljnim objektom
Tipi vzorcev Proxy • Remote Proxy • Lokalni predstavnik objekta, ki je v drugem naslovnem prostoru • Virtual Proxy • Dovoljuje tvorbo “na zahtevo” pomnilniško intenzivnega objekta. • Objekt bo tvorjen le, ko ga zares potrebujemo • Protection Proxy • Proxy nudi nadzor dostopa do resničnega objekta
Vzorec Proxy : primer • Pomislimo na program, ki mora naložiti in prikazati sliko • Ob zagonu programa, imamo indikacijo slike, ki naj bo prikazana • To je pomembno za oblikovalnike besedil in brkljalnike, ki z besedilom obkrožijo sliko, še preden je ta naložena • Image proxy zabeleži sliko, ki se nalaga