Metodologija razvoja softvera Dizajnerski abloni Design Patterns Lekcija
Metodologija razvoja softvera Dizajnerski šabloni- Design Patterns Lekcija. 03 Strukturalni šabloni Prof. dr Branko Perišić, bperisic@singidunum. ac. rs
Strukturalni Šabloni • Bave se načinom na koji se KLASE i OBJEKTI sastavljaju u složenije (veće) strukture. • KLASNI strukturni šabloni koriste mehanizam nasleđivanja za komponovanje interfejsa ili konkretnih implementacija. – Jednostavan primer je VIŠESTRUKO NASLEĐIVANJE!? ? – Klasni šablon ADAPTER – PRIVATNO NASLEĐIVANJE KLASA koje ADAPTIRA. • OBJEKTNI strukturalni šabloni – opisuju načine za komponovanje željene funkcionalnosti KOMBINOVANJEM OBJEKATA umesto sastavljanjem interfejsa ili konkretnih implementacija. • Dodatna osobina: MOGUĆNOST DINAMIČKOG MENJANJA STRUKTURE u fazi izvršavanja. (Nije moguće kod STATIČKOG SASTAVLJANJA KLASA).
Strukturalni Šabloni Obuhvat Klasa Objekat NAMENA Kreacioni Strukturalni Šabloni ponašanja Factory Method Adapter Interpreter Abstract Factory Adapter Chain of Responsibility Builder Bridge Command Prototype Composite Iterator Singleton Decorator Mediator Facade Memento Flyweight Observer Proxy State Strategy Visitor
Strukturalni Šabloni 2 Obuhvat Klasa NAMENA Kreacioni Strukturalni Šabloni ponašanja Factory Method Adapter Interpreter Abstract Factory Adapter Chain of Responsibility Builder Prototype Problem koji rešava: Command Bridge Composite Iterator Facade Memento Konvertuje interfejs. Composite klase u drugi – koji klijentska Singleton Decorator Mediator klasa očekuje. Objekat Adapter omogućava da klase, Observer koje nisu Flyweight dizajnirane da sarađuju, posredstvom njega Proxy obavljaju saradnju. State Strategy Visitor
Motivacija: Problemi nekompatibilnosti
Motivacija: Problemi nekompatibilnosti u softveru • Postoji aplikacija koja zahteva pristup drugoj bibliotečkoj aplikaciji ali servis koji želimo koristiti poseduje RAZLIČIT interfejs u odnosu na interfejs implementiran na strani aplikacije KOJA POZIVA. (želi da koristi). • Moguća rešenja: – Varijanta 1: Preprogramirati interfejs na strani APLIKACIJE KOJA POZIVA • Neprijatno, problematično, podložno greškama • Ekvivalentno promeni UTIKAČA (odsečemo kabl i montiramo novi utikač) – Varijanta 2: Preprogramirati interfejs na strani bibliotečke komponente • Možda ne posedujemo izvorni kod? • Šta se dešava sa drugim aplikacijama koje bi da koriste istu komponentu? • Nastaje veliki broj komponenti koje poseduju istu funkcionalnost ali različite interfejse preko kojih tu funkcionalnost eksponiraju. – Varijanta 3: ADAPTIRAJTE INTERFEJSE (Napište adapter) • Adapter konvertuje zahteve u formu koju ADAPTIRANI INTERFEJS (KOMPONENTA) može da prihvati.
Motivacija: Problemi nekompatibilnosti u softveru • Primer: Grafički editor • Crtanje i grafičke transformacije nad apstrakcijama Shape: koje su u stanju da se samostalno iscrtaju i transformišu. • Grafički elementi ne unose problem! • A TEKSTUALNI?
Struktura: – Adapter Klijent (klasa Client) Korisnik funkcionalnosti klase koja se adaptira posredno preko Adaptera. Adaptirana klasa (Adaptee) Pretpostavka je da se ova klasa ne može menjati Adapter Klasa koja vrši prilagođavanje. Nadležnost ove klase su konverzije tipova, parametara i sl. Najčešće kao mehanizam prilagođavanja koristi delegacija poziva metoda, ređe se koristi nasleđivanje.
Posledice: • KLASNI ADAPTER: – Prilagođava ADAPTIRANU i CILJNU KLASU. Šta se dešava ako ciljna klasa poseduje HIJERARHIJU NASPEDNIKA pri čemu je potrebno prilagoditi SVE NASLEDNIKE? – Omogućava da ADAPTER nadjača deo ponašanja ADAPTIRANE klase pošto je ADAPTER podklasa ADAPTIRANE klase. – Uvodi samo jedan OBJEKAT pa je njegovo referenciranje JEDNOSTAVNO. • OBJEKTNI ADAPTER: – Omogućava da JEDAN ADAPTER radi sa više ADAPTIRANIH KLASA – (osnovnom klasom i svim njenim podklasama) – Otežava NADJAČAVANJE ponašanja adaptirane klase (Adapter mora posedovati mehanizam za pristup podklasama!)
Adapter: - Implementacija Koncept Adaptera je relativno jednostavan, neophodno je napisati klasu koja poseduje željeni interfejs i učiniti da ona komunicira sa klasom koja poseduje drugačiji interfejs. To je moguće ostvariti uz oslonac na: • mehanizam nasleđivanja ili • kreiranje odgovarajuće kompozicije objekata. Prvi način podrazumeva izvođenje nove klase iz one koja nam ne odgovara i dodavanje metoda koje su neophodne da bi novoizvedena klasa zadovoljila zahteve željenog interfejsa. Drugi način podrazumeva da se postojeća klasa uključi unutar nove klase a zatim kreiraju metode koje prevode pozive unutar nove klase.
Adapteri u JAVI: • U sklopu JAVA programskog jezika postoji čitav niz ugrađenih adapterskih klasa: – Window. Adapter, – Component. Adapter, – Container. Adapter, – Focus. Adapter, – Key. Adapter, – Mouse. Adapter, i – Mouse. Motion. Adapter.
Adapteri u JAVI: • Jedan od problema u sklopu Java programskog jezike je što se prozori (windows) ne zatvaraju automatski kada se klikne mišem na Close ili Exit. • Generičko rešenje ovog problema je da osnovni prozor aplikacija (main Frame window) implementira Window. Listener interfejs, uz implementaciju jedino window. Closing rukovaoca. • Sama implementacija je prilično rogobatna!
Adapteri u JAVI: - Primer koda bez adaptera public void main. Frame extends Frame implements Window. Listener { public void main. Frame() { add. Window. Listener(this); //frame listens //for window events } public void window. Closing(Window. Event w. Evt) { System. exit(0); //exit on System exit box clicked } public void window. Closed(Window. Event w. Evt){} public void window. Opened(Window. Event w. Evt){} public void window. Iconified(Window. Event w. Evt){} public void window. Deiconified(Window. Event w. Evt){} public void window. Activated(Window. Event w. Evt){} public void window. Deactivated(Window. Event w. Evt){} }
Adapteri u JAVI: - Primena 1 //Ilustracija korišćenja Window. Adapter klase public class Closer extends Frame { public Closer() { Wind. Ap windap = new Wind. Ap(); add. Window. Listener(windap); set. Size(new Dimension(100, 100)); set. Visible(true); } static public void main(String argv[ ]) { new Closer(); } } //Prošireni Windows Adapter koji //zatvara Frejm kada se desi i prosledi odgovarajući događaj class Wind. Ap extends Window. Adapter { public void window. Closing(Window. Event e) { System. exit(0); } }
Adapteri u JAVI: - Primena 2 • Ilustracija korišćenjem anonimne unutrašnje klase. Window. Adapter klase //Kreiranje window listener-a za događaj window close add. Window. Listener(new Window. Adapter() { public void window. Closing(Window. Event e) {System. exit(0); } });
Adapter: – Srodni šabloni: • Bridge (Most) – sličan je po strukturu ali ima različitu namenu – da RAZDVOJI INTERFEJS od NJEGOVE IMPLEMENTACIJE, dok ADAPTER – menja interfejs postojećeg objekta. . • Decorator (Dekorater) – unapređuje drugi objekat bez izmene njegovog interfejsa. Transparentniji je za primenu i dozvoljava rekurzivno unapređenje. • Proxy – Definiše predstavnika ili surogat drugog objekta i ne menja njegove interfejse.
Adapter (Primer van domena softvera) Konverzija interfejsa klase u drugi koji klijent očekuje.
Adapter (Softverski primer) Java module Java Native Interface (JNI) C++ module
Strukturalni Šabloni – Bridge (Most) Obuhvat Klasa NAMENA Kreacioni Strukturalni Šabloni ponašanja Factory Method Adapter Interpreter Abstract Factory Adapter Chain of Responsibility Builder Bridge Command Composite Iterator Decorator Mediator Prototype Singleton Objekat Problem koji rešava: Razdvaja APSTRAKCIJU od. Memento njene Facade IMPLEMENTACIJE, čime omogućava njihovu Flyweight izmenu. Observer nezavisnu Proxy State Strategy Visitor
Bridge (Most): - Motivacija • Kada je potrebno da NEKA APSTRAKCIJA poseduje više različitih IMPLEMENTACIJA oslonac MEHANIZAM NASLEĐIVANJA pretstavlja uobičajeno rešenje! • Apstraktna klasa DEFINIŠE INTERFEJS APSTRAKCIJE koju enkapsulira, dok ga KONKRETNE PODKLASE IMPLEMENTIRAJU na različit način. • Mehanizam nasleđivanja TRAJNO VEŽE implementaciju sa apstrakcijom tako da je njihovo nezavisno menjanje, proširivanje i ponovno korišćenje TEŠKO.
Bridge (Most): - Motivacija • Problem: Raspoređivanje zadataka po NITIMA (Tredovima) u sklopu različitih operativnih sistema i različitih meranizama raspoređivanja. • Postoje dva gruba tipa raspoređivanja: – preemptive i – time sliced • Od operativnih sistema posmatrajmo: – Unix, – Linux i – Microsoft Windows • Sve kombinacije gornjih pojmova daju 6(šest) mogućnosti i ako bi za svaku od njih definisali posebni KLASU koja implementira konkretne raspoređivače u konkretnim OS-a dobili bi 6 KLASA. • Šta ako bi u to uključili i PLATFORME i MOGUĆE PRISTUPE IMPLEMENTACIJI? ?
Bridge (Most): - Motivacija Bridge rešenje
Bridge (Most): - Motivacija • BRIDGE (MOST) - vrši refaktorizaciju ovog eksplozivnog mehanizma nasleđivanja uvođenjem dve ORTOGONALNE HIJERARHIJE: – PLATFORMSKI NEZAVISNU – APSTRAKCIJA – PLATFORMSKI ZAVISNU – RAZLIČITE IMPLEMENTACIJE APSTRAKCIJE (različiti pristupi) se dodaju OVDE IMPLEMENTACIJE (različiti OS-ovi) se dodaju OVDE.
Bridge (Most): - Primenljivost • U situacijama: – Kada se želi izbeđi trajno vezivanje APSTRAKCIJE i njenih IMPLEMENTACIJA (npr. kada se izbor implementacije dešava u vreme izvršavanja ili se u vreme izvršavanja može menjati) – Kada je potrebno proširivati apstrakciju i njene implementacije novim podklasama (garantuje nezavisno proširivanje) – Kada promena u IMPLEMENTACIJI nesme da utiče na KLIJENTE. – Kada se želi SMANJITI BROJ KLASA u sklopu HIJERARHIJE (refaktorizacija) – Kada istu IMPLEMENTACIJU deli VIŠE OBJEKATA a da KLIJENT toga nije SVESTAN.
Bridge (Most): Učesnici • • Apstrakcija (Abstraction) – Definiše interfejs apstrakcije – Održava reference ka objektima klase Implementator. Finija. Apstrakcija (Refined. Abstraction) – Proširuje interfejs definisan od strane Apstrakcije (Abstraction) Implementator (Implementor) – Definiše interfejs implementacionih klasa. Interfejs ne mora da egzaktno odgovara interfejsu APSTRAKCIJE (mogu biti potpuno različiti). – Obično interfejs Implementatora sadrži samo osnovne operacije, dok Apstrakcija definiše operacije višeg nivoa (na osnovu osnovnih). Konkretni. Implementator (Concrete. Implementor) – Implementira interfejs Implementatora Saradnja: Apstrakcija prosleđuje klijentske zahteve objektu Implementator.
Bridge (Most): Posledice • Razdvajanje interfejsa od implementacije: – Implementacija nije trajno vezana sa interfejsom – Implementacija apstrakcije se može odgoditi do trenutka izvršavanja – Objekat može promeniti svoju implementaciju u fazi • Jednostavnije proširivanje: – Hijerarhije APSTRAKCIJA i IMPLEMENTATORA se mogu nezavisno proširivati. • Skrivanje implementacionih detalja od KLIJENTA.
Bridge (Most): Implementacija • Razdvajanje interfejsa od implementacije: – Implementacija nije trajno vezana sa interfejsom – Implementacija apstrakcije se može odgoditi do trenutka izvršavanja – Objekat može promeniti svoju implementaciju u fazi • Jednostavnije proširivanje: – Hijerarhije APSTRAKCIJA i IMPLEMENTATORA se mogu nezavisno proširivati. • Skrivanje implementacionih detalja od KLIJENTA.
Bridge (Most): Zadatak • Predpostavimo da posedujemo strukturu podataka čiji je sadržaj potrebno prikazivati na različite načine pri čemu je potrebno razdvojiti implementaciju od specifikacije i omogućiti proširivost. – Bridge! Jednostavna lista Struktura podataka Tabelirana Bridge lista . . .
Bridge (Most): – Srodni šabloni: • Abstract Factory – može poslužiti za kreiranje i konfigurisanje Bridge šablona. • Adapter – implementira mehanizam saradnje klasa koje nisu srodne. One se obično primenjuju na sisteme nakon njihovog projektovanja. Sa druge strane Bridge (Most) se koristi unapred da bi se apstrakcija i implementacija mogle nezavisno razvijati.
Strukturalni Šabloni – Composite Obuhvat Klasa NAMENA Kreacioni Strukturalni Šabloni ponašanja Factory Method Adapter Interpreter Abstract Factory Adapter Chain of Responsibility Builder Bridge Command Prototype Composite Iterator Decorator Mediator Facade Memento Singleton Objekat Problem koji rešava: Rukovanje hijerarhijama koje pretstavljaju strukturu Flyweight celine”. Observer “celina-deo Proxyelementarnim. State Uniformno rukovanje i složenim komponentama. Strategy Visitor
Sastav (Composite): Motivacija • Grafički editori dozvoljavaju izgradnju složenih dijagrama (objekata) na bazi jednostavnih komponenti. – – Korisnik može grupisati komponente u sklopove. . . koji se također mogu grupisati u složenije komponente. . .
Sastav (Composite): Problem • Iako grupišemo elemente, sistem nebi trebao tretirati rezultat kao PRIMITIVNI OBJEKAT (oblik). – Čak i ako ih večinu vremena jednako tretiramo – Možemo odlučiti da ih pregrupišemo • Ili da izmenimo atribut jednoe od komponenti grupisanog oblika. • SASTAV (Composite) šablon opisuje način na koji je moguće iskoristiti rekurzivnu kompoziciju tako da se mklijenti ne opterećuju strukturom.
Sastav (Composite): Stuktura • Sastav (Composite): Komponuje objekte u strukturu stabla u cilju pretstavljanja odnosa celina-deo celine. Dozvoljava da klijenti tretiraju pojedinačne objekte UNIFORMNO! – Ključ šablona pretstavlja apstraktna klasa koja zamenjuje i primitivne i složene elemente.
Sastav (Composite): Participanti • Komponenta (Component) – Deklariše interfejs objekata koji čine sastav; – Implementira podrazumevano ponašanje zajedničko za sve klase – Deklariše interfejs za pristup i rukovanje komponentakma koje cine sastav – (Opciono) definiše interfejs za pristup roditeljskoj komponenti i implementira je u slučaju da je to potrebno. • List (Leaf) – Pretstavlja objeka koji se nalazi na kraju strukture u sklopu sastava. List ne poseduje potomke! – Definiše ponašanje primitivnih objekata u sklopu sastava.
Sastav (Composite): Participanti • Sastav (Composite) – Deklariše ponašanje komponenti koje poseduju potomke; – Čuva komponente - potomke – Implementira operacije interfejsa Component koje se odnose na potomke, • Klijent (Client) – Manipuliše objektima u sastavu posretstvom interfejsa Component. – Ako je primalac List, zahtev se direktno obrađuje. – Ako je primalac Sastav, on prosleđuje zahtev podređenim komponentama uz eventualne operacije PRE ili POSLE prosleđivanja:
Sastav (Composite): Posledice • Definiše hijerarhije klasa koje se sastoje od primitivnih i složenih objekata – Primitivni objekti se mogu udruživati u složenije objekte, koji se rekurzivno mogu dalje strukturirati. – Kad god klijentski kod očekuje primitivni objekat bez posledica može preuzeti i kompozitni objekat. • Klijent se pojednostavljuje: – Klijent može tretirati kompozitne strukture i primitivne objekte UNIFORMNO. – Klijent nema znanje (i ne treba da brine) da li radi sa Listom ili sa Sastavom • Celokupno rešenje može postati “generičkije” nego što je potrebno: – Mana jednostavnog dodavanja komponenti je da se usložnjava sprečavanje uključivanja nekih komponenti u sastav: • U tom slučaju su neophodne PROVERE U FAZI IZVRŠAVANJA.
Strukturalni Šabloni – Composite
Implementacija • Eksplicitno referenciranje PARENTA? – U cilju pojednostavljivanja prolaska kroz strukturu moguće je uspostaviti referencu od potomka ka pretku. – Uobičajeno mesto za definisanje reference na roditelja je KOMPONENT-klasa. • Deklaracija operacija za rukovanje potomcima? – U prethodnom primeru apstraktna klasa Component deklariše metode Add i Remove koje obezbeđuju rukovanje potomcima, ali te metode LISTOVI ne pozivaju. – Da li je bolje ove operacije deklarisati u Composite klasi? – Odnos sigurnosti i transparentnosti: • Definisanjem interfejsa za rukovanje potomcima u sklopu KORENA obezbeđuje transparentnost (sve komponente se jednako tretiraju). Cena toga je sigurnost (neko može pokušati implementaciju besmislenih operacija kao što su dodavanje ili brisanje objekata sa LISTOVA) • Definisanje operacija rukovanja potomcima u sklopu klase Composite garantuje sigurnost (pokušaj brisanja ili dodavanja sa listova je moguće otkriti u procesu kompilacije), ali se gubi transparentnost (LISTOVI i STRUKTURE poseduju različit interfejs) • Koja struktura je najpogodnija za skladištenje komponenti? – Zavisi od efikasnosti. Moguće je čak da uopšte nije potrebna univerzalna struktura podataka!
Strukturalni Šabloni – Dekorater Obuhvat Klasa NAMENA Kreacioni Strukturalni Šabloni ponašanja Factory Method Adapter Interpreter Abstract Factory Adapter Chain of Responsibility Builder Bridge Command Prototype Composite Iterator Singleton Decorator Mediator Facade Memento Flyweight Observer Problem koji rešava: Objekat Rukovanje hijerarhijama koje pretstavljaju strukturu “celina-deo Proxy celine”. State Uniformno rukovanje elementarnim. Strategy i složenim komponentama. Visitor
Dekorater: Motivacija • Predpostavimo da naša aplikacija koristi Text. Box klasu koja enkapsulira prikazivanje teksta u sklopu rama. • Nekada je neophodno ramu dodati: – – • Ivice (različite vrste) Vertikalne klizače Horizontalne klizače. . . Kako dizajnirati klasu koja rešava ovaj problem?
Definišimo podklase za sve i svašta!
“Dekorišimo” originalni Text. Box • Fleksibilnije rešenje je uključivanje komponente u drugom objektu koja dodaje željeno ponašanje ili funkcionalnost. – Posmatrajmo to kao “omotavanje” originalnog objekta • “Omotani” objekat radi ono što je i ranije radio, ali poseduje dodatna svojstva – Ovaj “omotač”, ili dekorater, implementira interfejs komponente koju dekoriše. • Njegova predstava je sa strane klijenta komponente TRANSPARENTNA. – Dekorateri se mogu REKURZIVNO UGNEŽDAVATI, dozvoljavajući potencijalno neograničen broj proširenih svojstava ili odgovornosti.
Strukturalni Šabloni – Decorater
Participanti • • Component – Definiše interfejs koji omogučava dinamičko proširivanje odgovornosti. Concrete. Component – Definiše objekat kome se mogu pridružiti dopunske odgovornosti Decorator – Održava referencu ka komponenti (Component object) i definiše interfejs koji odgovara interfejsu komponente Concrete. Decorator – Dodaje odgovornosti komponenti
Mogućnost primene • Upotrebite Dekorater. . . – Ako želite dinamički i transparentno proširiti odgovornosti postojećih objekata, bez njihove modifikacije. – Za odgovornosti koje je moguće UKINUTI (povući) – Kada je proširivanje sa podklasama nepraktično. Ponekad je moguć veliki broj nezavisnih proširenja i dovodi do eksplozije broja podklasa u cilju podrške svih mogućih kombinacija. • Kako dekorater radi? – Dekorater prosleđuje zahteve komponent objektu koji dekoriše. – Može opciono obavljati dodatne operacije PRE ili POSLE prosleđivanja zahteva.
Posledice • (+) Fleksibilnije od statičkog nasleđivanja – Odgovornosti je moguće dodavati i ukidati u fazi izvršavanja. – Također je moguće jedno te isto svojstvo dodati VIŠE PUTA! • (+) Izbegava se uvođenje klasa koje opisuju opcije i dodatna svojstva na više nivoe hijerarhije. – Nudi mogućnost dodavanja odgovornosti po potrebi. – Umesto pokušaja obezbeđivanja podrške za sve moguće kombinacije proširenja u sklopu jedne složene klase, moguće je krenuti od jednostavne klase i DEKORISATI je po potrebi. • (-) Dekorater i njegova komponenta NISU IDENTIČNI – Sa aspekta IDENTITETA OBJEKATA dekorisana komponenta nije identična originalnoj komponenti. • (-) Veliki broj jednostavnih objekata – Sistemi koji su sastavljeni od velikog broja jednostavnih objekata koji svi liče jedan na drugog. – Jednostavno se podešava ali ga je teško razumeti i TESTIRATI.
Implementacija • Usklađivanje interfejsa – Interfejs objekta dekoratera mora biti usklađen sa interfejsom objekta koji DEKORIŠE. • Izostavljanje Apstraktne klase Dekorater – Nije potrebno deklarisati apstraktnu klasu Dekorater ako želite dodati samo jedno prošireno svojstvo ili odgovornost. • Održavanje Component klasa jednostavnim – U cilju obezbeđenja jedinstvenosti interfejsa KOMPONENTE i DEKORATERI moraju poticati od ZAJEDNIČKE KOMPONENT KLASE. – Važno je da klasa spada u kategoriji “laganih”(lightweight) • Definicija predstave podataka treba biti prepuštena PODKLASAMA. • Kompleksnost KOMPONENT KLASE može uzrokovati da DEKORATERI postanu prekompleksni u masovnoj primeni. • Promena omotača objekta u odnosu na promenu njegove suštine – DEKORATER treba posmatrati kao omotač (kožu - skin) oko objekta koji menja ponašanje omotanog objekta. – Ako je cilj promeniti SUŠTINU objekta moguće je koristiti Strategy!
Java I/O stream-ovi su Dekorateri! • Postoji apstraktna komponenta. . . – Input. Stream • . . . nekoliko konkretnih komponenti. . . – File. Input. Stream – String. Buffer. Input. Stream – Byte. Array. Input. Stream –. . . • . . . apstraktni Dekorater – Filter. Input. Stream • . . . skup konkretnih Dekoratera – Pushback. Input. Stream – Buffered. Input. Stream – Data. Input. Stream – Line. Number. Input. Stream –. . .
Strukturalni Šabloni – Facade Obuhvat Klasa Objekat NAMENA Kreacioni Strukturalni Šabloni ponašanja Factory Method Adapter Interpreter Abstract Factory Adapter Chain of Responsibility Builder Bridge Command Prototype Composite Iterator Singleton Decorator Mediator Facade Memento Flyweight Problem koji rešava: Observer Proxy State Obezbeđenje jedinstvenog interfejsa za skup Strategy podsistema. Visitor
Strukturalni Šabloni – Facade
Facade – Fasada Šablon • Obezbeđuje jedinstven interfejs za skup interfejsa u sklopu nekog podsistema – Definiše interfejs visokog nivoa koji omogućava jednostavnije korišćenje nekog podsistema • Strukturiranje sistema po podsistemima omogučava smanjenje složenosti; – Zajednički cilj projektovanja je minimizacija komunikacije i zavisnosti između podsistema;
Primer primene - Facade
Mogućnost primene • Koristiti kada. . . – Želite obezbediti jednostavan interfejs nekom složenom podsistemu; • Podsistemi postaju sve kompleksniji u toku celokupnog životnog ciklusa; • Fasada obezbeđuje jednostavan podrazumevani pogled na podsistem koji je dovoljno dobar za standardne klijente; • Klijenti kojima je potrebno nešto više moraju se podržati na drugi način. (van okvira Fasade); – Postoji veliki broj veza zavisnosti između klijenata i implementacionih klasa neke apstrakcije; • Fasada razdvaja podsisteme od klijenata i drugih podsistema čime promoviše nezavisnost i prenosivost podsistema; – Je neophodnu ugneždavanje podsistema; • Fasada se koristi za definisanje ulazne tačke (entry point) za svaki nivo podsistema; • Ako između podsistema postoje zavisnosti, moguće je te zavisnosti pojednostaviti svođenjem na isključivu komunikaciju posredstvom fasada;
Struktura • Fasada: – Ima svest o klasama koje implementiraju podsistem i njihovoj odgovornosti za opsluživanje zahteva; – Delegira klijentske zahteve odgovarajućim objektima podsistema; • Klase podsistema: – Implementiraju funkcije podsistema; – Rukuju zadacima dodeljenim od strane Fasada-objekta; – Ne poseduju svest o fasadi (ne referenciraju fasadu);
Posledice • Izolacija klijenata od podsistema: – Redukuje broj objekata sa kojima klijenti moraju komunicirati; – Pojednostavljuje korišćenje podsistema; • Nizak nivo snage veza (coupling) između podsistema i klijenata: – Izmena delova podsistema ne utiće na klijente! – Smanjuju se zavisnosti u fazi kompilacije i izgradnje softverskih sistema; • Ne sprečava da aplikacije, ako je potrebno, koriste klase definisane u sklopu podsistema: – Projektant može da slobodno bira između jednostavnosti korišćenja i opštosti (generičnosti) rešenja;
Facade (Nesoftverski primer) Obezbeđivanje jedinstvenog interfejsa za skup interfejsa u sklopu sistema.
Facade (Softverski primer)
Strukturalni Šabloni – Muva Obuhvat Klasa Objekat NAMENA Kreacioni Strukturalni Šabloni ponašanja Factory Method Adapter Interpreter Abstract Factory Adapter Chain of Responsibility Builder Bridge Command Prototype Composite Iterator Singleton Decorator Mediator Facade Memento Flyweight Observer Problem koji rešava: Proxy State Oslonac na mehanizam delenja. Strategy u cilju efikasnog podržavanja rada sa velikom brojem Visitor jednostavnih objekata! objekata
Problem: document editori. . . • OO-editori dokumenata uobičajeno koriste objekte u cilju predstavljanja sadržanih elemenata (tabele, slike, animacije i sl. ). – Šta bi se desilo ako bi svakji karakter u tekstu predstavljao objekat? • Fleksibilnije rešenje od tog nije moguće!
Veliki broj malih objekata. . . • Da li je praktično svaki karakter tretirati kao objekat? – Jednostavno je doći do stotina hiljada karakter objekata. • Svaki od njih predstavlja karakter, njegovu poziociju, font, veličinu, stil i sl.
Ali. . . • Ako delimo objekte koji se nalaze u istom bazenu objekata, rukovanje svakim karakterom kao objektom postaje praktično. – Svaki “muva” objekat skladiši kod karaktera. Njegovu poziciju u sklopu dokumenta i tipografski stil moguće je utvrditi primenom algoritma za formatizaciju i prezentaciju teksta.
Klas model prethodnog primera Apstraktna klasa grafičkog objekta
MUVA (Flyweight) obrazac • Koristi DELENJE u cilju efikasne podrške velikom broju sitno granuliranih objekata. • Primenjivost: Koristiti samo ako su SVI ODGOVORI na sledeća pitanja TAČNI: – Aplikacija koristi VELIKI BROJ OBJEKATA – TROŠKOVI SKLADIŠTA PODATAKA su VISOKI zbog vekilog zauzeća delovima koji su DELJIVI (moguće ih je deliti između više objekata) – Večinu objekata je moguće OGOLITI – Mnogobrojnu grupu objekata je moguće zameniti relativno malim brojem deljenih objekata nakon OGOLJAVANJA. – APLIKACIJA ne zavisi od IDENTITETA OBJEKATA (kako se MUVA objekti DELE, test provere IDENTITETA rezultira vrednošću TAČNO za konceptualnog različite objekte)
Struktura i participanti • • MUVA (Flyweight) – Deklariše interfejs posretstvom koga muve mogu dobiti i postupati sa OGOLJENIM stanjem. KONKRETNA MUVA (Concrete. Flyweight) – • Implementira Muva Interfejs i dodaje mehanizme za skladištenje pojedinačnih karakteristika, ako postoje. Konkretna. Muva mora biti DELJIVA! NEDELJIVA MUVA (Unshared. Flyweight) – • • Nije obavezno da sve Muva podklase budu deljive. Interfejs omogućava deljenje ali ga ne NAMEĆE! Fabrika. MUVA (Flyweight. Factory) – MUVA – Održava referencu na MUVA OBJEKTE. Formira OGOLJENO stanje MUVE. Nebi trebao da direktno instancira Konkretnu. Muvu, Mora je ekskluzivno dobit od strane Flyweight. Factory objekta u cilju korektne implementacije DELENJA. Kreira i rukuje OBJEKTIMA. KLIJENT(Client) – –
Posledice • Muve mogu doprineti porastu troškova pri instanciranju (run-time) zbog: PRENOSA, PRONALAŽENJA i/ili IZRAČUNAVANJA OGOLJENOG STANJA. – Ovi troškovi se kompenziraju uštedama u prostoru i ušteda raste sa porastom DELENJA. • Uštede u prostoru za skladištenje zavise od niza činilaca: – Redukcija ukupnog broja instanci kao posledica DELJENJA – Potrebana vezanim za skladištenje SPECIFIČNOSTI pojedinačnih MUVA OBJEKATA – NAČINA FORMIRANJA OGOLJENOG STANJA (dinamički ili statički)
Flyweight (Nesoftverski primer) Koristi delenje u cilju efikasne podrške velikom broju sitno granuliranih objekata.
Flyweight (Softverski primer) Memory
Strukturalni Šabloni – Proxy Obuhvat Klasa NAMENA Kreacioni Strukturalni Šabloni ponašanja Factory Method Adapter Interpreter Abstract Factory Adapter Chain of Responsibility Builder Bridge Command Prototype. Problem Composite koji rešava: Singleton Objekat Iterator Decorator Mediator Facade Memento Flyweight Observer Proxy State Strategy Visitor
Problemi prilikom otvaranja VELIKIH dokumenata • Posmatrajmo dokument editor koji podržava uključivanje GRAFIČKIH objekata kao sastavnih delova dokumenta: – Neki grafički objekti (npr. Velike bit-mape (slike) su izuzetno zahtevne za kreiranje. –. . . želimo da se dokument otvara BRZO! • Trebalo bi odjednom kreirati sve objekte ovog tipa! –. . . potrebni su nam podatci sa svake slike (npr. Visina, širina i sl. ) od samog početka! • Stojimo pred dilemom: NE ŽELIMO ODMAH KREIRATI SVE ZAHTEVNE OBJEKTE ali nam je POTREBNA INFORMACIJA o njima! • Koje alternative postoje?
Proxy obrazac • Proxy: Obezbeđuje SUROGAT ili kontejner za objekat u cilju kontrolisanja pristupa tom objektu: – U gornjem primeru Document. Editor puni Image. Proxy umesto stvarnog grafičkog objekta. Samo ako je potrebno ISCRTATI objekat (Draw()) Image. Proxy će ga tada otvoriti (napuniti).
Mogućnost primene • Proxy je moguće primeniti kad god postoji potreba za složenim (sofisticiranim) načinom referenciranja OBJEKATA umesto uobičajenog korišćenja POKAZIVAČA NA OBJEKAT (pointer) • Mogući scenariji: – Remote Proxy: Obezbeđuje lokalnu predstavu posmatranog OBJEKTA ali u drugom adresnom prostoru (prostoru imena); – Virtual Proxy: Kreira “zahtevne” objekte po potrebi (opisani primer); – Protection Proxy: Kontroliše pristup originalnom objektu (korisno ako je jednom objektu moguć pristup od strane više klijenata sa različitim pravima pristupa); – Smart Reference: Zamena za jednostavne pokazivače sa ciljem da se podrže dodatne akcije prilikom pristupa objektu; • Utvrđivanje broja referenciranja stvarnog objekta tako da se on može OSLOBODITI kada više ne postiji potreba za njim. • Provera da li je STVARNI OBJEKAT ZAKLJUČAN (ekskluzivno rezervisan) pre PRISTUPA u cilju obezbeđenja od drugih konkurentnih pristupa. • . . .
Učesnici • Proxy – Održava reference koje omogućavaju da proxy pristupa stvarnom subjektu. Proxy može referencirati Subjeka ako Realni. Subjekat i Subjekat poseduju identičan interfejs. – Obezbeđuje interfejs koji je identičan interfejsu Subjekta tako da proxy može biti zamenjen umesto stvarnog subjekta. – Kontroliše psristup realnom subjektu i potencijalno ga KREIRA ili UNIŠTAVA. – Ostale odgovornosti zavise od tipa proxy-ja:
Učesnici • Subjekat (Subject) – Definiše zajednički interfejs za Real. Subject i Proxy tako da se Proxy može koristiti na bilo kom mestu gde je Real. Subject neophodan
Učesnici • Realni Subjekat (Real. Subject) – Definiše stvarni objekat koji Proxy “zastupa”;
Posledice • Zavisno od tipa proxy-ja, nivo indirekcije koji on uvodi donosi različite prednosti: – Remote proxy može SAKRITI činjenicu da stvarni objekat postoji u drugom adresnom prostoru: – Virtual proxy može podržati OPTIMIZACIJU kao što je kreiranje objekta na zahtev. – Protection proxies i Smart references omogućavaju dodatne operacije u trenutku pristupa objektu. • Drugo poboljšanje koje Proxy obrazac skriva od korisnika je kopiranje prilikom zapisivanja (copy-on-write): – Kopiranje velikih objekata može biti “skupo”, tako kada klijent zahteva KOPIJU moguče mu je proslediti SUROGAT (Prioxy); – Stvarno KOPIRANJE objekta se ODLAŽE do trenutka modifikacije kopije. • Napomena: Iako dekorater može posedovati sličnu implementaciju kao proxy, dekorateri imaju potpuno drugačiju ulogu. Oni dodaju jednu ili više odgovornosti OBJEKTU dok Proxy kontroliše PRISTUP objektu.
Strukturalni Šabloni – Proxy
Proxy (ne softverski primer) Obezbeđuje surogat ili kontejner za drugi objekat u cilju kontrole pristupa.
Proxy (Softvarski primer)
Strukturalni Šabloni – Proxy - Primer
Strukturalni Šabloni – Rekapitulacija Ako treba da: Koristimo? • se postojeća komponenta ponovno iskoristi u sklopu novog projekta a pri tome postoji neusaglašenost interfejsa • ponovno korišćena komponenta sarađuje sa drugim komponentama sistema sa kojima pre toga nije bila povezivana Adapter • interfejsi komponente budu odvojeni od njihove implementacije/a • klijent bude “pošteđen brige” o promenama u sklopu implementacije (re-link umesto re-compile. ) • izbor konkretne implementacije bude podesiv u fazi izvršenja • "interfejs" i "implementacija" budu nezavisno otvoreni za proširenja ali zatvoreni za izmene • se “povežu" komponente koje pretstavljaju "implementaciju" odnosno da više komponenti podele implementaciju umesto da je dupliciraju! Bridge
Strukturalni Šabloni – Rekapitulacija Ako treba da: • podržimo rekurzivno komponovanje sistema • podržimo hijerarhijsko slaganje komponenti po principu “celinadeo celine" • klijenti budu u mogućnosti da transparentno rade sa složenim (npr. stablo) i jednostavnim (npr. čvor) komponentama. • komponente budu proširive u fazi izvršenja • funkcionalnost bude “ugneždena”. Klijenti moraju imati mogućnost konfigurisanja bilo koje kombinacije svojstava jednostavnom definicijom livoa (sloja) koji je potrebno primeniti. • obezbedimo jednostavan interfejs ka složenim podsistemima • sistem treba da obezbedi alternativne interfejse (početni, srednji i napredni) • sistem treba da razdvoji svoje podsisteme • sistem podrži “ugneždavanje" podsistema. Koristimo? Composite Decorator Facade
Strukturalni Šabloni – Rekapitulacija Ako treba da: • kombinujemo veliki broj komponenti niskog stepena granulacije • podržimo “prozivanje” i ponovno korišćenje nečega što je konačno u maniru beskonačnih potreba! • podržimo “distribuiranu obradu" tako što ćemo obezbediti lokalnu predstavu jedne te iste komponente u različitom adresnom prostoru. • podržimo "lazy creation“ (odloženo kreiranje) – komponenta se kreira jedino ako i kada korisnik to eksplicitno zatraži • sistem upravlja pristupom komponentama preko posrednika koji proverava identitet i prava pristupa klijenta • podržimo višedimenzionalne indirekcije Koristimo? Flyweight Proxy
Metodologija razvoja softvera Dizajnerski šabloni - Design Patterns Lekcija: 04. Strukturalni Šabloni
- Slides: 83