home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 March / Chip_2004-03_cd1.bin / redakce / chip_txt / txt / 142-143.txt < prev    next >
Text File  |  2004-01-31  |  10KB  |  47 lines

  1. High Order Messaging 
  2. Druhß zprßva o HOM
  3. High Order Messaging (dßle jen HOM) je objektovß technologie, kterß umo₧nφ podstatn²m zp∙sobem zjednoduÜit k≤d a zv²Üit jeho flexibilitu. P°ed Φasem jsme se seznßmili s jejφmi zßklady (viz Chip 12/02 nebo www.ocs.cz/Text/HOM.html). Dnes se seznßmφme se zßkladnφmi principy, na nich₧ je technologie HOM zalo₧ena. 
  4.  
  5. HOM bychom mohli voln∞ p°elo₧it jako "nep°φmΘ zasφlßnφ zprßv". P°i objektovΘm programovßnφ objektu b∞₧n∞ posφlßme zprßvy, jejich₧ prost°ednictvφm si vy₧ßdßme n∞jakΘ akce (Java vyu₧φvß jinΘ terminologie - mφsto zasφlßnφ zprßv hovo°φ o volßnφ metod; my vÜak budeme vyu₧φvat standardnφ objektovΘ terminologie a budeme mluvit o zprßvßch). 
  6.  
  7. Z┴KLADY 
  8. Princip HOM spoΦφvß v tom, ₧e zprßvu nezasφlßme p°φmo. Mφsto toho "mezi objekt a zprßvu" vlo₧φme dalÜφ p°φkaz, kter² urΦφ, co se se zprßvou mß stßt. Jednφm z nejjednoduÜÜφch p°φklad∙ m∙₧e b²t opo₧d∞nΘ odeslßnφ zprßvy: nap°φklad chceme, aby se okno zav°elo za deset sekund. ╪eÜenφm HOM je pou₧φt specißlnφ "high-order" zprßvu, je₧ objektu °ekne: "Nßsledujφcφ zprßvu mßÜ dostat za deset sekund." Zßpis v Objective C by vypadal takto: 
  9.  
  10. [[okno afterDelay:10] close]; 
  11.  
  12. Mo₧nostφ vyu₧itφ slu₧eb HOM je °ada. Velmi vhodnΘ jsou pro prßci s poli, kde uÜet°φ spoustu p°φkaz∙ for: staΦφ zavΘst HOM zprßvu each, kterß poli °ekne: "Nßsledujφcφ zprßvu p°edej ka₧dΘmu ze sv²ch prvk∙." Takto t°eba zav°eme vÜechna okna v poli: 
  13.  
  14. [[poleOken each] close]; 
  15.  
  16. A takto ulo₧φme do samostatnΘho pole jejich titulky nebo vybereme jen ta okna, je₧ jsou prßv∞ viditelnß: 
  17.  
  18. NSArray *titulky=[[poleOken collect] title]; NSArray *vo=[[poleOken select] isVisible]; 
  19.  
  20. Principem funkce HOM je vyu₧itφ tzv. zßstupnΘho objektu. Vra¥me se k p°φkladu se zavφrßnφm oken. Zajistφme, aby libovoln² objekt po p°ijetφ zprßvy afterDelay: vytvo°il a vrßtil nov² objekt t°φdy °ekn∞me DelayedPerformer. Ten bude obsahovat pouze odkaz na p∙vodnφho p°φjemce zprßvy a v naÜem p°φpad∞ takΘ Φasov² interval, urΦujφcφ dobu, na kterou se mß zpracovßnφ zprßvy odlo₧it. Objekt t°φdy Delayed Performer p°φmo nezpracovßvß ₧ßdnou zprßvu. Mφsto toho ve chvφli, kdy jakoukoli zprßvu dostane, ud∞lß dv∞ v∞ci (viz obrßzek): 
  21. zprßvu i jejφ p°φpadnΘ argumenty si zapamatuje (nynφ tedy objekt obsahuje trojici ·daj∙: p∙vodnφho p°φjemce zprßvy, Φasov² interval a zprßvu); 
  22. spustφ ΦasovaΦ (s d°φve ulo₧en²m Φasov²m intervalem), po jeho₧ uplynutφ p°edß ulo₧enΘmu objektu ulo₧enou zprßvu. U polφ zprßva each vytvo°φ a vrßtφ nov² zßstupn² objekt, t°eba t°φdy Trampoline, kter² obsahuje jen odkaz na pole, je₧ bylo p∙vodnφm p°φjemcem zprßvy. Jakmile objekt t°φdy Trampoline dostane n∞jakou zprßvu, rozeÜle ji vÜem objekt∙m z pole, na n∞₧ mß v sob∞ odkaz. 
  23. Slo₧it∞jÜφ je to u zprßv, je₧ vracejφ n∞jakou hodnotu - collect, select apod. Zprßva collect nejen₧e rozeÜle zprßvu vÜem objekt∙m z pole, ale navφc v²sledek ka₧dΘho odeslßnφ ulo₧φ do novΘho pole, je₧ pak vrßtφ. Zprßva select prozkoumß v²sledek odeslßnφ zprßvy a do novΘho pole ulo₧φ ty z p∙vodnφch objekt∙, pro n∞₧ zprßva vrßtila pravdivou Φi nenulovou hodnotu. Obdobn∞ lze konstruovat i dalÜφ, slo₧it∞jÜφ HOM zprßvy. 
  24. Ani °et∞zenφ zprßv nenφ ₧ßdn² technick² problΘm: nejjednoduÜÜφ je, kdy₧ zßstupnΘ objekty mφsto jednΘ zprßvy (ji₧ si pamatujφ pro odeslßnφ cφlovΘmu objektu) majφ pro zprßvy celΘ pole. Do n∞j se zprßvy uklßdajφ a p°i vlastnφm zpracovßnφ se odeÜlou vÜechny "najednou" (prvnφ zprßva z pole se poÜle cφlovΘmu objektu, v²sledku se ihned poÜle zprßva druhß, v²sledku se poÜle t°etφ atd.). 
  25. Potom je jednoduchß i implementace specißlnφch zprßv begin a end, je₧ umo₧≥ujφ °et∞zenφ zprßv (i t∞ch, je₧ s HOM nemajφ nic spoleΦnΘho). Zprßva begin v zßstupnΘm objektu zvedne pomocn² ΦφtaΦ, zprßva end jej op∞t snφ₧φ. Zßstupn² objekt vyu₧φvß ΦφtaΦ p°i rozhodovßnφ, zda zprßvy uklßdat, nebo rovnou zpracovat: jde-li o HOM zprßvu nebo je-li ΦφtaΦ nenulov², zprßva se ulo₧φ. 
  26. Implementace slu₧eb popsan²ch v minulΘm textu o slu₧bßch HOM u₧ by m∞la b²t vcelku z°ejmß: t°eba zprßva safely prost∞ vytvo°φ zßstupn² objekt, kter² svΘmu cφlovΘmu objektu poÜle zprßvu v rßmci zabezpeΦenΘho v²jimkovΘho bloku (try... pro Javu, NS_DURING... NS_HANDLER pro Objective C). Zprßva inNewThread vytvo°φ zßstupn² objekt, kter² svΘmu cφlovΘmu objektu poÜle zprßvu v samostatnΘm threadu. 
  27. Specißlnφ technika vÜak je zapot°ebφ pro implementaci automatickΘ synchronizace mezi thready na zßklad∞ vrßcenΘ hodnoty. P°ipome≥me si, o co jde: slu₧ba, je₧ spouÜtφ nov² thread, m∙₧e vrßtit tzv. zßstupn² objekt fault. Ten pouze udr₧uje vazbu na thread a Φekß, a₧ mu kdokoli poÜle jakoukoli zprßvu. Potom zßstupn² objekt vyvolß slu₧bu wait (poΦkß, a₧ thread skonΦφ), nahradφ sßm sebe skuteΦn²m v²sledkem threadu a nakonec jeÜt∞ tomuto v²sledku poÜle zprßvu, ji₧ sßm dostal. V programovacφm jazyce s vyu₧itφm HOM je to jednoduchΘ: 
  28.  
  29. NSArray *seznam=[[database future] complicatedSearch]; ... printf("%d prvk∙",[seznam count]); 
  30.  
  31. Slu₧ba future spustφ nov² thread a v n∞m p°edß objektu database zprßvu complicated Search stejn∞, jako by to ud∞lala zprßva inNewThread. Zprßva future vÜak navφc vytvo°φ specißlnφ zßstupn² HOM objekt °ekn∞me t°φdy ArrayFault a ten vrßtφ mφsto po₧adovanΘho pole. Objekt ArrayFault obsahuje odkaz na thread, v n∞m₧ probφhß zpracovßnφ; thread zase obsahuje odkaz na ArrayFault. Jestli₧e objekt ArrayFault dostane libovolnou zprßvu, zapamatuje si ji a vyu₧ije systΘmov²ch slu₧eb pro °φzenφ thread∙ k tomu, aby poΦkal na ukonΦenφ threadu, na n∞j₧ je vßzßn. Pak zprßvu poÜle sßm sob∞. (Znφ to divn∞? ╚t∞te dßl!) 
  32. Jakmile thread skonΦφ, poslednφ instrukce threadu ulo₧φ v²sledek do pam∞ti na mφsto objektu ArrayFault (objekt ArrayFault zanikne, nebo¥ jeho data jsou p°epsßna daty objektu, jen₧ je v²sledkem prßce threadu). To znamenß, ₧e pokud zßstupn² objekt ArrayFault poslal zprßvu "sßm sob∞" (tj. na svou vlastnφ adresu), ve skuteΦnosti ji poslal objektu, jen₧ je v²sledkem threadu. To proto, ₧e ukonΦenφ threadu objekt ArrayFault v pam∞ti tφmto v²sledkem nahradilo. 
  33.  
  34. JAZYKOV┴ PODPORA
  35. Jestli₧e majφ slu₧by HOM fungovat s libovoln²m p°φjemcem zprßv, je t°eba, aby zprßvy typu afterDelay Φi each byly k dispozici pro libovoln² objekt. To znamenß, ₧e chceme-li implementovat HOM, musφme mφt mo₧nost p°idßvat novΘ metody ke ko°enovΘ t°φd∞ (aby byly k dispozici kterΘmukoli objektu kterΘkoli t°φdy). V dob°e navr₧en²ch objektov²ch jazycφch to nenφ problΘm (Objective C k tomu mß tzv. kategorie). V jazycφch typu Javy, je₧ kategorie ani obdobnou slu₧bu nemajφ, to vÜak znamenß mφt mo₧nost zasßhnout p°φmo do zdrojov²ch k≤d∙ ko°enovΘ t°φdy. 
  36. Nutnostφ je, aby objektov² programovacφ jazyk podporoval polymorfismus, jin²mi slovy, aby bylo mo₧nΘ objektu zaslat libovolnou zprßvu s tφm, ₧e konkrΘtnφ zpracovßnφ tΘto zprßvy zßvisφ na objektu samotnΘm. To je d∙sledek toho, ₧e zßstupn² objekt (Delayed Performer) musφ b²t schopen p°ijmout jakoukoli zprßvu, nebo¥ ji sßm nezpracovßvß. 
  37. U jazyk∙ typu Javy nebo C++ zde op∞t narazφme - polymorfismus podporujφ pouze zΦßsti, jen v rßmci d∞dickΘ hierarchie t°φd (a v Jav∞ takΘ rozhranφ). Vytvo°it objekt, jen₧ p°ijφmß libovolnou zprßvu, v nich mo₧nΘ nenφ (v Jav∞ to mo₧nΘ je, pokud vyu₧ijeme slu₧by java.lang. reflect; problΘm vÜak je v tom, ₧e nem∙₧eme vyu₧φvat standardnφ syntaxi pro p°edßvßnφ zprßv a zßpis programu se komplikuje). 
  38. DalÜφ podmφnkou pro implementaci HOM je, aby bylo mo₧nΘ zprßvu vzφt a jako objekt ulo₧it do prom∞nnΘ (a odeslat pozd∞ji). Zde jde spφÜe o slu₧by standardnφch knihoven; v Jav∞ lze op∞t za cenu nepohodlφ vyu₧φt slu₧by java.lang.reflect. Standardnφ knihovny Objective C obdobnΘ slu₧by p°φmo nepodporujφ. Objective C se vÜak se standardnφmi knihovnami u₧ tΘm∞° nevyu₧φvß, b∞₧n∞ se pou₧φvajφ bohatÜφ knihovny zalo₧enΘ na standardu OpenStep (nap°. Cocoa). Tam je k dispozici t°φda NSInvocation, urΦenß k uklßdßnφ zprßv a jejich argument∙. 
  39. Poslednφ "trik", kter² musφ programovacφ jazyk pro implementaci HOM nabφzet, je zpracovßnφ obecnΘ zprßvy. To ·zce souvisφ s polymorfismem i s uklßdßnφm zprßv: mß-li objekt t°φdy DelayedPerformer b²t schopen p°ijmout (a ulo₧it a pozd∞ji p°edat) jakoukoli zprßvu, musφme mφt v jazyce nebo ve standardnφch knihovnßch podporu pro implementaci "neznßmΘ zprßvy". 
  40. V Objective C (s knihovnami a runtime zalo₧en²mi na standardu OpenStep) takovß podpora je. Standardn∞ tam platφ, ₧e pokud objekt dostane zprßvu, pro ni₧ nenφ v jeho t°φd∞ ani v ₧ßdnΘ z rodiΦovsk²ch t°φd definovßna metoda, runtime zprßvu i jejφ argumenty automaticky "zabalφ" do objektu t°φdy NSInvocation a ten cφlovΘmu objektu p°edß jako argument zprßvy forwardInvocation:. 
  41. Äßdnß ze souΦasn²ch verzφ Javy nic podobnΘho standardn∞ neobsahuje. Jeliko₧ ale Java p°φmo nepodporuje ani polymorfismus, musφme se p°i implementaci HOM stejn∞ obrßtit na vhodn² preprocesor a v rßmci jeho maker implementovat vlastnφ konvenci obdobnou zprßv∞ forwardInvocation: z Objective C. 
  42. Zßstupn² objekt typu fault je nahrazen jin²m objektem, tak₧e moduly, je₧ s objektem pracujφ, v∙bec "nepost°ehnou zm∞nu". To vy₧aduje zßsah do objektovΘho systΘmu na pom∞rn∞ nφzkΘ ·rovni. V Objective C je to mo₧nΘ dφky jeho "cΘΦkovΘmu" d∞dictvφ a dφky tomu, ₧e objektovß struktura je ve°ejn∞ zdokumentovßna (objekty obsahujφ odkaz na svou t°φdu a odkaz je na nφzkΘ ·rovni p°φstupn²). Bohu₧el, v Jav∞, pokud mi je znßmo, nic podobnΘho nenφ mo₧nΘ. 
  43.  
  44. TO JE ZAT═M VèE... 
  45. Do tohoto Φlßnku se u₧ vφce informacφ o HOM nevejde. P°φÜt∞ si vÜak ukß₧eme konkrΘtnφ implementaci HOM a seznßmφme se i s n∞kter²mi praktick²mi p°φklady pou₧itφ. Vφce informacφ o HOM vΦetn∞ zdrojov²ch text∙ (anglicky) lze najφt na adrese www.metaobject.com.
  46.  
  47.