RSS

Uszanowanko Programowanko #33: jak projektować aplikacje

Liczba odsłon: 68

Po pierw­szym za­chłyś­nię­ciu się umie­jęt­no­ścią zmu­sze­nia kom­pu­te­ra do wy­ko­ny­wa­nia za­pi­sy­wa­nych w pro­gra­mie po­le­ceń, więk­szość pro­gra­mis­tów stwier­dza po­trze­bę pi­sa­nia pro­gra­mów nie tyl­ko co­raz bar­dziej funkcjo­nal­nych, ale też krót­szych, przej­rzy­stych i nie­za­wod­nych. Osiągnię­cie te­go ce­lu wy­ma­ga sto­so­wa­nia po­praw­nej, czys­tej archi­tek­tu­ry oraz od­po­wied­nie­go po­kry­cia ko­du pro­gra­mu te­sta­mi auto­ma­tycz­ny­mi.

Tym dwóm za­gad­nie­niom by­ło po­świę­co­ne 33. spot­ka­nie gru­py „Uszanowanko Programowanko”, któ­re od­by­ło się 14 lis­to­pa­da w gli­wic­kiej sie­dzi­bie The Software House. Poniższy tekst za­wie­ra re­la­cję z te­go wy­da­rze­nia.

Jako pierw­sza wy­stą­pi­ła Anna Widera, pro­gra­mist­ka apli­kac­ji iOS. Jej pre­zen­tac­ja by­ła za­ty­tu­ło­wa­na „Object orien­ted vs proto­col orien­ted, czy­li o tym, jak prze­ło­żyć skom­pli­ko­wa­ny świat w przej­rzy­sty kod”. Prelegentka roz­po­czę­ła od przy­pom­nie­nia za­sto­so­wań tech­ni­ki dzie­dzi­cze­nia, pod­kre­śla­jąc jej klu­czo­we zna­cze­nie w ogra­ni­cza­niu re­dun­dan­cji tek­stu źród­ło­we­go opro­gra­mo­wa­nia obiek­to­we­go. Następ­nie za­de­mon­stro­wa­ła uży­cie tej tech­ni­ki na przy­kła­dzie pros­tej hie­rar­chii klas re­pre­zen­tu­ją­cych pot­wo­ry w grze, po­sia­da­ją­ce pew­ne ce­chy i zdol­no­ści (bieg, lot, atak). Wskazała przy tym na prob­lem wy­ni­ka­ją­cy z bra­ku moż­li­woś­ci do­wol­ne­go wska­zy­wa­nia ze­sta­wu cech po­szcze­gól­nych pot­wo­rów: je­że­li ol­brzy­mia więk­szość klas pot­wo­rów ma dys­po­no­wać moż­li­woś­cią cho­dze­nia lub bie­gu, jed­nak te naj­bar­dziej groź­ne mo­gą la­tać, ale nie cho­dzić i bie­gać, nie mo­że­my me­tod reali­zu­ją­cych po­ru­sza­nie się po lą­dzie wpi­sać do wspól­nej kla­sy ba­zo­wej.

Rozwią­za­niem jest zmia­na po­dej­ścia z czys­to obiek­to­we­go na ba­zu­ją­ce na pro­to­ko­łach (ang. proto­col orien­ted). Protokół to ele­ment ję­zy­ka Swift przy­po­mi­na­ją­cy inter­fejs, jed­nak mo­gą­cy dys­po­no­wać do­myśl­ną im­ple­men­tac­ją za­de­kla­ro­wa­nych w nim me­tod. Klasa mo­że rea­li­zo­wać wie­le pro­to­ko­łów (za­pew­niać z ni­mi zgod­ność), a w efek­cie łą­czyć wie­le nie­za­leż­nych de­fi­ni­cji me­tod w spo­sób przy­po­mi­na­ją­cy dzie­dzi­cze­nie wie­lo­ba­zo­we, co sta­no­wi reali­zac­ję kon­cep­cji wtrą­ceń (mixin). Istnieje też moż­li­wość uza­leż­nia­nia wtrą­ca­nych im­ple­men­tac­ji pro­to­ko­łów (ang. exten­sions) od reali­zo­wa­nia in­nych pro­to­ko­łów przez skła­da­ną kla­sę.

Po wstę­pie teore­tycz­nym pre­le­gent­ka raz jesz­cze za­im­ple­men­to­wa­ła hie­rar­chię klas pot­wo­rów z fik­cyj­nej gry. Tym ra­zem jed­nak każ­da kla­sa pot­wo­ra, choć dzie­dzi­czy­ła z jed­nej kla­sy ba­zo­wej, do­dat­ko­wo za­pew­nia­ła zgod­ność ze wska­za­ny­mi pro­to­ko­ła­mi okreś­la­ją­cy­mi ce­chy cha­rak­te­ry­stycz­ne dla da­nej ka­te­gorii pot­wo­rów. Dzięki te­mu do­stęp­ne by­ły tyl­ko me­to­dy, któ­re wprost od­po­wia­da­ły za­cho­wa­niu da­nej ka­te­gorii pot­wo­rów, a do­dat­ko­wo – bez ko­niecz­noś­ci pi­sa­nia ani wier­sza ko­du! – do klas zo­sta­ły wtrą­co­ne właś­ci­we do­myśl­ne im­ple­men­tac­je tych me­tod.

Kolejna część pre­zen­tac­ji by­ła po­świę­co­na kwestii na­zy­wa­nia pro­to­ko­łów. Prelegentka przed­sta­wi­ła trzy ka­te­go­rie pro­to­ko­łów:

Wszystkie przed­sta­wio­ne do te­go mo­men­tu in­for­mac­je zo­sta­ły ze­bra­nie na ko­niec pre­zen­tac­ji w se­rii przy­kła­dów prak­tycz­nych, w któ­rych pre­le­gent­ka po­ka­za­ła wzię­te z ży­cia za­sto­so­wa­nia tech­ni­ki pro­to­ko­łów. Dzięki wy­dzie­le­niu pro­to­ko­łów od­po­wie­dzial­nych za ko­lo­ro­wa­nie ele­men­tów inter­fej­su użyt­kow­ni­ka oraz uza­leż­nie­niu do­myśl­nej im­ple­men­tac­ji tych pro­to­ko­łów od in­nych inter­fej­sów rea­li­zo­wa­nych przez kla­sy, moż­li­we sta­ło się łat­we usta­la­nie ko­lo­ry­sty­ki wska­za­nych ele­men­tów for­mu­la­rza przez sa­mo do­da­nie naz­wy pro­to­ko­łu do de­fi­ni­cji kla­sy. Takie pod­nie­sie­nie po­zio­mu ab­strak­cji pro­gra­mo­wa­nia jest kro­kiem na dro­dze do tech­nik pro­gra­mo­wa­nia in­ten­cjo­nal­ne­go, w któ­rym pro­gra­mis­ta nie za­pi­su­je wprost za­cho­wań pro­gra­mu, lecz okre­śla je zbio­rem cech.

Pokazane przez Annę Widerę tech­ni­ki nie są czymś cał­kiem no­wym czy też wy­jąt­ko­wym dla ję­zy­ka Swift. Stanowią jed­nak cie­ka­we uzu­peł­nie­nie tra­dy­cyj­nych, „czys­tych” tech­nik obiek­to­wych, po­zwa­la­jąc pod­nieść po­ziom ab­strak­cji tek­stu źród­ło­we­go pro­gra­mu i zmniej­szyć je­go obję­tość. Warto jed­nak pa­mię­tać o na­stę­pu­ją­cych kwes­tiach:

Prezenta­cja by­ła świet­nie przy­go­to­wa­na i po­pro­wa­dzo­na. Ciekawym po­mys­łem by­ło wcześ­niej­sze za­re­jes­tro­wa­nie wszyst­kich de­mon­stra­cji w for­mie sek­wen­cji wideo, dzię­ki cze­mu pod­czas sa­me­go wy­stą­pie­nia nie by­ło miej­sca na żad­ne po­mył­ki.


Drugą pre­zen­tac­ję, za­ty­tu­ło­wa­ną „Wstęp do Clean Architecture”, po­pro­wa­dził Damian Zawadzki, pro­gra­mis­ta apli­kac­ji sys­te­mu An­droid. Zaczął od pod­kreś­le­nia ro­li archi­tek­tu­ry w roz­wo­ju opro­gra­mo­wa­nia oraz po­zy­tyw­ne­go wpły­wu tech­nik ta­kich jak SOLID na łat­wość i szyb­kość wpro­wa­dza­nia zmian i udos­ko­na­leń w ko­dzie. Następ­nie prze­szedł do opi­su za­sad archi­tek­tu­ry Clean. Podsta­wo­wą za­sa­dą jest wy­dzie­le­nie częś­ci tek­stu źród­ło­we­go pro­gra­mu cał­ko­wi­cie nie­za­leż­nej od za­sto­so­wa­nej osno­wy pro­gra­mi­stycz­nej, war­stwy skła­do­wa­nia da­nych czy też bi­blio­te­ki inter­fej­su użyt­kow­ni­ka. Tą część, na­zy­wa­ną do­me­ną apli­kac­ji, obu­do­wu­je­my na­stęp­nie war­stwą de­ta­li, któ­rych za­da­niem jest do­pa­so­wa­nie do­me­ny do oto­cze­nia sprzę­to­we­go, sys­te­mo­we­go i pro­gra­mo­we­go.

Podstawo­wy­mi ele­men­ta­mi de­fi­niu­ją­cy­mi do­me­nę apli­kac­ji są przy­pad­ki uży­cia (ang. use case). Każdy przy­pa­dek jest za­mo­de­lo­wa­ny w po­sta­ci od­dziel­nej kla­sy. Dane wcho­dzą­ce i wy­cho­dzą­ce z obiek­tu przy­pad­ku uży­cia są za­her­me­ty­zo­wa­ne w od­ręb­nych obiek­tach DTO. Zewnętrzne usłu­gi reali­zu­ją­ce kon­kret­ne dzia­ła­nia we współ­dzia­ła­niu z kom­po­nen­ta­mi sys­te­mu opera­cyj­ne­go lub in­ny­mi bi­blio­te­ka­mi – wspom­nia­ne de­ta­le – ope­ru­ją z kolei na encjach, czy­li obiek­tach spe­cy­ficz­nych dla da­nej reali­zac­ji usłu­gi. Obiekty usłu­go­we są umiesz­cza­ne w do­me­nie po­przez me­cha­nizm wstrzy­ki­wa­nia za­leż­noś­ci tak, aby do­me­na by­ła za­leż­na wy­łącz­nie od inter­fej­sów, a nie kon­kret­nych reali­zac­ji. Z kolei ca­ły pro­ces tłu­ma­cze­nia da­nych wi­do­ku oraz en­cji na obiek­ty DTO (i vice ver­sa) jest rea­li­zo­wa­ny przez obiek­ty ty­pu mapper.

Prelegent za­de­mon­stro­wał wdro­że­nie oma­wia­nej archi­tek­tu­ry na przy­kła­dzie pros­te­go mo­du­łu uwie­rzy­tel­nia­ją­ce­go. W ra­mach do­me­ny po­wsta­ła kla­sa przy­pad­ku uży­cia Sign­In­Use­Case, przyj­mu­ją­ca obiekt DTO Credentials i zwra­ca­ją­ca obiekt DTO Profile. Wewnętrznie dzia­ła­nie przy­pad­ku uży­cia jest rea­li­zo­wa­ne przez trzy ze­wnętrz­ne mo­du­ły usłu­go­we:

Każdy z tych mo­du­łów zo­stał zde­fi­nio­wa­ny w for­mie inter­fej­su, któ­re­go reali­zac­ja zna­laz­ła się po­za do­me­ną. W ten spo­sób w do­me­nie znaj­du­je się je­dy­nie kod wprost od­po­wia­da­ją­cy przy­pad­ko­wi uży­cia, roz­drab­nia­ją­cy zło­żo­ną ope­ra­cję na po­je­dyn­cze kro­ki wy­ma­ga­ją­ce inter­akcji z ze­wnętrz­ny­mi usłu­ga­mi. Dzięki te­mu war­stwę do­me­ny moż­na prze­no­sić do in­nych apli­kac­ji wy­ma­ga­ją­cych reali­zac­ji tych sa­mych dzia­łań, na­wet je­że­li są one uru­cha­mia­ne w zu­peł­nie in­nym śro­do­wis­ku. Właściwe im­ple­men­tac­je de­ta­li usłu­go­wych są do­łą­cza­ne w za­leż­noś­ci od do­ce­lo­we­go śro­do­wis­ka i wstrzy­ki­wa­ne zgod­nie z kon­cep­cją od­wra­ca­nia za­leż­noś­ci.

Opisana archi­tek­tu­ra po­zy­tyw­nie wpły­wa nie tyl­ko na prze­noś­ność ko­du oraz łat­wość, z ja­ką moż­na go mo­dy­fi­ko­wać, ale też na zdol­ność ko­du do tes­to­wa­nia go za po­mo­cą te­stów auto­ma­tycz­nych. Oderwanie lo­gi­ki biz­ne­so­wej od za­leż­noś­ci zew­nętrz­nych – głów­nie inter­fej­su użyt­kow­ni­ka oraz ba­zy da­nych – ułat­wia imi­to­wa­nie zew­nętrz­nych mo­du­łów, a za­tem ca­ło­ścio­we te­sto­wa­nie do­me­ny apli­kac­ji.

Do za­let opi­sa­ne­go po­dej­ścia archi­tek­to­nicz­ne­go pre­le­gent za­li­czył prze­de wszyst­kim zwięk­sze­nie pro­duk­tyw­no­ści wy­ni­ka­ją­ce ze sto­so­wa­nia jed­nej przej­rzy­stej archi­tek­tu­ry w ra­mach ca­łe­go ze­spo­łu oraz pro­duk­tu. Łatwiejsze sta­je się prze­no­sze­nie pro­gra­mis­tów po­mię­dzy róż­ny­mi ze­spo­ła­mi pro­duk­to­wy­mi oraz po­wtór­ne wy­ko­rzys­ty­wa­nie frag­men­tów ko­du w in­nych apli­kac­jach. Wyraźne roz­dzie­le­nie częś­ci do­me­no­wej oraz po­szcze­gól­nych de­ta­li ułat­wia też zrów­no­leg­la­nie pra­cy nad pro­jek­tem. Tak, jak zo­sta­ło też wspom­nia­ne wcześ­niej, du­żo łat­wiej jest uzys­kać wy­so­kie po­kry­cie ko­du te­sta­mi jed­nost­ko­wy­mi.

Wdrażanie tak wy­sub­li­mo­wa­nej archi­tek­tu­ry nie­sie ze so­bą rów­nież wa­dy. Najpoważ­niej­szą jest ol­brzy­mi po­cząt­ko­wy na­kład pra­cy zwią­za­ny ze zde­fi­nio­wa­niem klas przy­pad­ku uży­cia, usług zew­nętrz­nych, obiek­tów DTO oraz kon­wer­te­rów (mapper). W przy­pad­ku prost­szych usług mo­że to ozna­czać za­stą­pie­nie kil­ku­dzie­się­ciu wier­szy tek­stu jed­ne­go pod­pro­gra­mu kil­ku­na­sto­ma od­dziel­ny­mi kla­sa­mi po kil­ka­dzie­siąt wier­szy tek­stu źród­ło­we­go każ­da, a to wią­że się oczy­wiś­cie z kil­ka­naś­cie ra­zy dłuż­szym cza­sem pra­cy. W skraj­nych przy­pad­kach, gdy two­rzo­ny pro­gram jest bar­dzo pros­ty, sto­so­wa­nie opi­sa­nej archi­tek­tu­ry mo­że być wręcz nie­opła­cal­ne i nie po­win­no mieć miej­sca.

Swoją pre­zen­tac­ję pre­le­gent pod­su­mo­wał stwier­dze­niem, że lep­szą sytua­cją jest, je­że­li coś nie dzia­ła, jed­nak usu­nię­cie uster­ki jest pros­te dzię­ki czy­tel­nej archi­tek­tu­rze, niż je­że­li coś dzia­ła ideal­nie, ale wpro­wa­dza­nie zmian jest trud­ne, cza­so­chłon­ne, kosz­tow­ne i wręcz nie­bez­piecz­ne. Wspomniał też, że pro­gra­miś­ci nie­ustan­nie la­wi­ru­ją w trój­ką­cie „make it work”, „make it right”, „make it fast”, a opi­sy­wa­na archi­tek­tu­ra po­zwa­la uzys­kać więk­sze zrów­no­wa­że­nie speł­nie­nia tych trzech ce­lów.

Prezenta­cja Damiana Zawadzkiego wy­pad­ła nie­co sła­biej niż po­zo­sta­łe, głów­nie ze wzglę­du na nie­co chao­tycz­ne pro­wa­dze­nie oraz bar­dzo du­żą licz­bę wpla­ta­nych an­gli­cyz­mów, głów­nie nie­prze­tłu­ma­czo­nych ter­mi­nów tech­nicz­nych. Należy jed­nak pa­mię­tać, że mi­mo że wy­stą­pie­nie mia­ło cha­rak­ter wpro­wa­dze­nia do te­ma­tu, za­wie­ra­ło na­praw­dę du­żo szcze­gó­ło­wych in­for­mac­ji a pre­le­gent do­kła­dał wszel­kich sta­rań, by przed­sta­wić wszyst­ko w moż­li­wie naj­bar­dziej przy­stęp­ny spo­sób i zmieś­cić się przy tym w przy­zna­nym mu cza­sie.


Ostatnią pre­zen­tac­ję, za­ty­tu­ło­wa­ną „How to TDD your MVP: testing mo­bile apps”, przed­sta­wił Michał Bujalski, pro­gra­mis­ta apli­kac­ji sys­te­mu An­droid. Zaczął on swo­je wy­stą­pie­nie od za­py­ta­nia uczest­ni­ków spot­ka­nia kto z nich spot­kał się wcześ­niej z tech­ni­ką TDD, a kto w ogó­le pi­sze te­sty jed­nost­ko­we do two­rzo­ne­go ko­du. Zgło­si­ło się cał­kiem spo­ro osób, jed­nak zde­cy­do­wa­nie nie więk­szość. Jako wy­ja­śnie­nie ta­kie­go sta­nu rze­czy pre­le­gent po­dał cza­so­chłon­ność pi­sa­nia te­stów, szcze­gól­nie we­ry­fi­ku­ją­cych już na­pi­sa­ny i dzia­ła­ją­cy kod, a tak­że zja­wi­sko naz­wa­ne ASAP-driven de­ve­lop­ment, przy któ­re­go wy­stę­po­wa­niu nie ma cza­su nie tyl­ko na pi­sa­nie te­stów, ale na­wet na cał­ko­wi­te zam­knię­cie właś­ci­wych prac im­ple­men­ta­cyj­nych. W efek­cie ko­du nie obej­mu­je się te­sta­mi, bo nie zo­stał on na­pi­sa­ny z myś­lą o tes­tach, a pi­sze się go bez myś­le­nia o tes­tach, gdyż nie na­pi­sa­ło się do nie­go te­stów.

Tymcza­sem te­sty auto­ma­tycz­ne ma­ją do­sko­na­ły wpływ na pro­ces po­wsta­wa­nia opro­gra­mo­wa­nia. Dają pew­ność, że po­szcze­gól­ne ope­rac­je koń­czą się po­myśl­nie i zwra­ca­ją spo­dzie­wa­ne wy­ni­ki. Oszczę­dza­ją czas, gdyż uster­ki moż­na łat­wo zlo­ka­li­zo­wać. Ułatwiają do­da­wa­nie no­wych funkcjo­nal­noś­ci oraz re­fak­to­ry­za­cję ko­du, gdyż zmia­ny moż­na wpro­wa­dzać bez stra­chu, że ist­nie­ją­ce funkcjo­nal­noś­ci prze­sta­ną dzia­łać po­praw­nie. Koniecz­ność do­sto­so­wa­nia ko­du do te­stów po­wo­du­je też, że sta­je się on bar­dziej mo­du­lar­ny i przej­rzy­sty.

Najbardziej wy­ra­fi­no­wa­ną for­mą tes­to­wa­nia jed­nost­ko­we­go jest po­dejś­cie TDD, na­zy­wa­ne też cza­sem TFD. Progra­mo­wa­nie zgod­nie z tą me­to­do­lo­gią roz­po­czy­na się od za­pi­sa­nia inter­fej­su te­sto­wa­ne­go mo­du­łu oraz zbio­ru te­stów we­ry­fi­ku­ją­cych po­praw­ność dzia­ła­nia. Ponie­waż nie ist­nie­je na tym eta­pie jesz­cze żad­na im­ple­men­tac­ja me­to­dy, wszyst­kie te­sty mu­szą za­koń­czyć się nie­po­wo­dze­niem. Dopiero te­raz pro­gra­mis­ta, uzbro­jo­ny w do­dat­ko­wą do­ku­men­tac­ję w po­sta­ci treś­ci i opi­su te­stów, przy­stę­pu­je do za­pi­sy­wa­nia me­tod, stop­nio­wo speł­nia­jąc wa­run­ki po­zy­tyw­ne­go przej­ścia te­stów.

Szczegól­nym wy­zwa­niem jest te­sto­wa­nie apli­kac­ji mo­bil­nych. Kod reali­zu­ją­cy funkcjo­nal­ność częs­to jest w ta­kim przy­pad­ku moc­no po­wią­za­ny z os­no­wą pro­gra­mi­stycz­ną właś­ci­wą dla da­nej plat­for­my mo­bil­nej. Występują ob­szer­ne blo­ki ko­du z prze­ni­ka­ją­cy­mi się cza­sem war­stwa­mi wi­do­ku i ste­ro­wa­nia. Proponowa­nym roz­wią­za­niem jest za­stą­pie­nie mo­de­lu MVC przez MVP. W sto­sun­ku do MVC, dwie pod­sta­wo­we róż­ni­ce to:

Luźna in­te­grac­ja warstw zna­czą­co uprasz­cza te­sto­wa­nie inter­fej­su użyt­kow­ni­ka. Ponie­waż ca­ła lo­gi­ka wi­do­ku jest prze­nie­sio­na do war­stwy pre­zen­te­ra, mo­że­my pod­sta­wić imi­tac­ję war­stwy wi­do­ku i spraw­dzać, jak ak­ty­wo­wa­nie po­szcze­gól­nych dzia­łań wpły­wa na stan wi­do­ku i mo­de­lu.

Stosowa­nie mo­de­lu MVP umoż­li­wia ko­do­wa­nie inter­fej­su użyt­kow­ni­ka zgod­nie z me­to­do­lo­gią TFD. Testy sta­ją się w tym przy­pad­ku częś­cią pro­ce­su pro­gra­mo­wa­nia, a pro­gra­mis­ta mo­że sku­pić się na spo­so­bie dzia­ła­nia i za­cho­wa­niu ko­du, a nie na de­ta­lach im­ple­men­ta­cyj­nych. Dodatkowo, te­sty sta­no­wią wstęp­ną do­ku­men­tac­ję, a nie­ja­ko „za dar­mo” do­sta­je się wy­so­ki po­ziom po­kry­cia te­sta­mi.

Prelegent za­chę­cił do za­pi­sy­wa­nia te­stów zgod­nie z re­gu­ła­mi given-when-then. Jasno roz­dzie­la­my w ten spo­sób część te­stu kon­fi­gu­ru­ją­cą śro­do­wis­ko te­sto­we, wy­ko­nu­ją­cą tes­to­wa­ną czyn­ność oraz we­ry­fi­ku­ją­cą wy­ni­ko­wy stan śro­do­wis­ka. O ta­kiej kon­struk­cji te­stów pi­sa­łem już w re­lac­ji ze SpreadIT 2017.

W ra­mach ses­ji de­mon­stra­cyj­nej Michał Bujalski po­ka­zał pros­tą apli­ka­cję reali­zu­ją­cą uwie­rzy­tel­nia­nie za po­mo­cą naz­wy kon­ta użyt­kow­ni­ka oraz has­ła. Po przy­go­to­wa­niu szkie­le­tu ko­du za­pi­sał te­sty spraw­dza­ją­ce dzia­ła­nie we­ry­fi­ka­to­ra po­praw­noś­ci da­nych uwie­rzy­tel­nia­ją­cych oraz pre­zen­te­ra. Następ­nie, po uzys­ka­niu błęd­nych wy­ni­ków we wszyst­kich tes­tach, za­czął uzu­peł­niać kod, uwzględ­nia­jąc przy tym prze­wi­dzia­ne wcześ­niej przy­pad­ki, ta­kie jak błęd­ne da­ne uwie­rzy­tel­nia­ją­ce, błąd uwie­rzy­tel­nia­nia oraz błąd ko­mu­ni­kac­ji z ser­we­rem.

Podsumo­wu­jąc swo­je wy­stą­pie­nie, Michał Bujalski po­dał na­stę­pu­ją­ce za­le­ce­nia:


Listopadowe spot­ka­nie z cyk­lu „Uszanowanko Programowanko” by­ło świet­nie zor­ga­ni­zo­wa­ne. Wszystkie wy­stą­pie­nia prze­bie­ga­ły bez prob­le­mu i w prze­wi­dzia­nych ra­mach cza­so­wych, a piz­za sta­no­wią­ca tło dla ses­ji „net­wor­kin­gu” do­tar­ła na czas. Po raz ko­lej­ny też hall The Software House zo­stał wy­peł­nio­ny po brze­gi uczest­ni­ka­mi.

Merytorycznie wszyst­kie trzy pre­zen­tac­je sta­ły na wy­so­kim po­zio­mie (z wcześ­niej wy­mie­nio­ny­mi uwa­ga­mi). Jest to du­że osiąg­nię­cie w aspek­cie fak­tu, że na każ­dym spot­ka­niu wy­stę­pu­je za­zwy­czaj cał­ko­wi­cie in­ny ze­staw pre­le­gen­tów.