4. Komponenttien vuorovaikutus Roolirajapinnat Välittäjät Kutsun siirtäminen Edustajat Takaisinkutsut Tapahtumat Sovittimet Tehtaat 1
Toteutusriippuvuuksien poistaminen rajapinnoilla A B A ei tunne A IB B miten mitä 2
Rooliperustaiset rajapinnat Client1 Services Client2 Client1 Server Role1 Server Client2 Role2 3
Esimerkki VisualComponent Button EventSource 4
Hienojakoiset roolirajapinnat Asiakkaat X Y Z Roolit A B C D Palvelun tarjoajat P:n perinteinen rajapinta P Q Q:n perinteinen rajapinta 5
Komponenttien vuorovaikutuksen hallinta välittäjällä Joukko keskenään kommunikoivia komponentteja Ongelmia: komponenttien väliset riippuvuudet mutkikkaita ja vaikeita hallita jos jokin yhteistoiminta halutaan erikoistaa, joudutaan jokainen osallistuja erikoistamaan komponentteja ei voi käyttää toisessa yhteydessä 6
Esimerkki 7
Esimerkki Ilmanlaadun hallinta avaa ikkuna Ikkunoiden hallinta sulje ilmastointi Ilmastoinnin hallinta 8
Välittäjä Etuja: vuorovaikutus omana kokonaisuutena (välittäjä), voidaan räätälöidä koskematta komponentteihin tekee komponentit riippumattomiksi toisistaan yksinkertaistaa kommunikaatiota (yksi-moneen, ei moni-moneen) Ongelma: keskitetty kontrolli voi kasvaa itsessään monimutkaiseksi 9
Coordinator widgetchange(widget) Esimerkki ListBox ListBoxI getselected(): str Dialog Coordinator TextField TextFieldI settext(str) Widget changed() Button ButtonI enable() 10
Tyypillinen vuorovaikutus ListBox DialogCoordinator TextField Button widgetchange getselected settext enable 11
Esimerkki Ilmanlaadun hallinta avaa ikkuna sulje ilmastointi Ikkunoiden hallinta Ilmastoinnin hallinta 12
Kutsun siirtäminen A ei tunne Bimp opimp() imp A op op() B A op op() B imp.opimp(); 13
Kutsun siirtäminen: esimerkki Chargable discount(int): int CustomerSupport discount(int): int Account Manager Customer KeyCustomer Support 14
Periytymisen toteutus kutsun siirtämisell misellä Täydellinen" Car olio printdescription self Car parent Vehicle parent Commodity parent printdescription: {printname;... } 15
Periytymisen toteutus kutsun siirtämisell misellä Täydellinen" Car olio printdescription self Car parent Vehicle parent Product parent Commodity parent printdescription: {printname;... } 16
Komponenttiriippuvuuksien poistaminen edustajalla Edustaja: komponentti, joka edustaa toista komponenttia jossain yhteydessä ilman, että komponentin asiakkaat tietävät tätä Asiakas op Edustaja op Varsinainen komponentti 17
Sovelluksia hajautetut järjestelmät (esim. EJB) viivästetty lataaminen (esim. oliokannat) älykkäät osoittimet... 18
Edustaja suunnittelumalli Client Services request()... actual.request() Proxy request() actual Server 19
Esimerkki: viivästetty lataaminen Navigator Map getname() getroute(from,to) varsinainen getroute palvelu return mapname; MapProxy map CityMap if not loaded then map = loadfromfile(); loaded = true end; map->getroute() getname getroute getname getroute 20
Riippuvuuksien poistaminen takaisinkutsuilla Takaisinkutsu Tekniikka, jonka avulla palvelun pyytäjä voi saada kontrollin kesken palvelun suorituksen Tavallisesti palvelu kuuluu johonkin yleiskäyttöiseen kirjastoon, joka ei saa tulla riippuvaksi kirjastoa käyttävistä sovelluksista. Takaisinkutsu mahdollistaa sovelluskohtaisen räätälöinnin yleiskäyttöisille palveluille ilman, että ne tulevat riippuviksi sovelluksista. 21
Takaisinkutsu kirjasto sekvenssikaaviona: : Kirjasto : Sovellus palvelun kutsu palvelun kutsu paluu takaisinkutsu takaisinkutsu paluu palvelun paluu sovellus takaisinkutsu 22
Takaisinkutsurajapinta EngineUser warn(str) Takaisinkutsurajapinta if (oilpressure<limit) { user.warn();... run() Engine myeng = new Engine(); myeng.setuser(this); myeng.start(); PowerSource start() stop() setuser(engineuser) Car setup() warn(str)... Yleiskäyttöinen Sovelluskohtainen log.output("oil pressure low"); myeng.stop(); 23
Käytetään n poikkeuksia? Voidaanko poikkeuksilla saada periaatteessa aikaan sama kuin takaisinkutsuilla? A Ei koskaan B Joskus harvoin C Usein D Aina 24
Poikkeuksilla Engine run() if (oilpressure<limit) {... throw new Oilpressure(); }... PowerSource start() throws Oilpressure stop() setuser(engineuser) setup():... myeng = new Engine(); myeng.setuser(this); try { myeng.start(); } catch (Oilpressure op) {warn("...");} Erot: Edut: Haitat: Yleiskäyttöinen Car setup() warn(str)... - ei takaisinkutsurajapintaa - käyttävän yksikön (Car) tulee varautua poikkeukseen - yksinkertaisempi - kirjastoyksikön ei tarvitse tietää mitään käyttävän yksikön operaatioista (edes takaisinkutsurajapintaa) - kirjastoyksikkö ei voi jatkaa tapahtuman käsittelyn jälkeen (tässä tosin ei ilmeisesti tarvitsekaan) Sovelluskohtainen log.output(str+": Oil pressure low"); myeng.stop(); 25
Riippuvuuksien vähentv hentäminen tapahtumien avulla Tapahtuma on ohjelman ajoaikainen tila, jolla on oma nimetty esitysmuotonsa ohjelmassa ja joka edellyttää yhden tai useamman komponentin reagointia. Tapahtuman aiheuttaja ei tunne tapahtumaan reagoivia yksiköitä 26
Palvelun kutsuja Perinteinen kutsu vs. tapahtuma Tapahtuman aiheuttaja Palvelun tarjoaja Tapahtuma Tapahtumaan reagoivat 27
Tapahtumat käyttk yttöliittymissä GUI Käyttäjän komennot Tilamuutokset Sovelluslogiikka 28
Synkroninen takaisinkutsuihin perustuva tapahtumankäsittely rekisteröinti Reagoivat yksiköt Tapahtuman aiheuttaja ilmoitus tapahtumasta (takaisinkutsu) 29
Tarkkailija suunnittelumalli Observer update(event) SourceComp obs src ObserverComp Source register(observer) unregister(observer) 30
Tapahtumien käsittely k Javassa: Esimerkki ActionListener actionperformed(actionevent) JMenuItem obs src AppComp AbstractButton addactionlistener(actionlistener) 31
Rajapintariippuvuuksien poistaminen sovittimilla Rajapinnan A mukainen palvelupyyntö Sovitin Rajapinnan B mukainen Komponentti 1 palvelupyyntö Komponentti 2 Sovitin: palvelun pyytäjän ja tarjoajan välillä oleva ohjelmayksikkö, joka tekee palvelun pyytäjän riippumattomaksi palvelun tarjoajan rajapinnasta. 32
Sovitin suunnittelumalli AbstractServices request() Client ConcreteServices concrequest()... adaptee.concrequest() Adapter request() adaptee Server 33
Esimerkki: BeanBox (Sun) 34
Sovittimien käyttk yttö riippumattomien komponenttien tapahtumapohjaisessa kommunikoinnissa rekisteröinti ilmoita tapahtumasta palvelukutsu Komponentti A Sovitin Komponentti B 35
BeanBox: Java toteutus generoitu sovitin-luokka: public class Hookup_1734b2d565 implements java.awt.event.actionlistener, java.io.serializable { public void settarget( sunw.demo.juggler.juggler t) { target = t; } public void actionperformed( java.awt.event.actionevent arg0) { target.stopjuggling(); } Kun mouse-click tapahtuma tulee, aktivoidaan stopjuggling -operaatio } private sunw.demo.juggler.juggler target; 36
Luontiriippuvuuksien vähentv hentäminen tehtaalla FactoryRegistry register(factory) AppInit Factory create(): Product AppFactory <<create>> Platform <<create>> Product service AppProduct 37
Yksinkertainen tehdas: Tehdasmetodi suunnittelumalli Product Creator factorymethod anoperation product = factorymethod();... AppProduct create ConcCreator factorymethod return new AppProduct(); 38
Esimerkki <<interface>> Document open() close() use DocManager createdocument() newdocument() opendocument() doc = createdocument(); docs.add(doc); doc.open(); MyDocument open() close() create MyDocManager createdocument() return new MyDocument; 39
Ongelma: Miten varmistaa yhdenmukaiset oliot? Alusta TAI MUTTA EI: 40
ShapeFac Ratkaisu: yksi tehdasolio luo kaikki oliot yhdenmukaisesti tehdasluokka TwoDimFac ilmentymä tehdasolio käyttää Alusta luo ilmentymä ThreeDimFac factory class 41
Abstrakti tehdas suunnittelumalli: Esimerkki AbsFactory createbutton(): Button createmenu(): Menu Sovellusalusta WinFactory Button Menu <<create>> WinButton WinMenu 42