6. October 2010

Singleton je antipattern

Medzi návrhové vzory sa priplietol aj jeden nepodarok, ktorému sa hovorí singleton.

Sám o sebe singleton nie je zlý. Zlé však je, že vývojári majú tendenciu skĺznuť k jeho abnormálnemu nadužívaniu. Keď to poviem inak: namiesto používania rozumu a dobrého dizajnu používajú singletony.

Singleton znižuje možnosti rozširovania a testovania aplikácie. Osobne by som ho označil skôr za antipttern, než pattern.

Ak sa začnú v projekte množiť singletoni geometrickou radou, tak máte problém. Dôsledky premrštenej singletonizácie vedú doslova do vývojárskeho pekla. Softvér môžete rovno zahodiť.

Typicky vývojár singletonom supluje neexistenciu globálneho stavu a nedostatok znalostí o iných možnostiach riešenia.

Takže prosím. Pozor na singletona, ak vám niekto povie, že je to skvelá vec, mala by sa vám v ušiach rozoznieť varovná siréna.

Existujú prípady, kedy má použitie singletona význam, ale aj vtedy je nutné postupovať opatrne.

1. January 2010

Revízia 2009

Už je to raz tak, 2009 išiel pápá. Tak, čo sa všetko podarilo a čo stálo za to?

Začiatok 2009. Šeď všedných dní lemovaná náročnými úlohami, ktoré by dokázali úspešne zamestnať stredne veľké oddelenie Research and Development. Už ma to nebavilo. Ako sa hovorí: “Šialenstvo je dookola robiť rovnaké veci a očakávať iný výsledok.” Iný výsledok sa akosi dlho nedostavoval, tak som sa začal obávať o mieru šialenstva, ktorú moja práca prinášala.

Prvá veľká zmena prišiela 30. 5. 2009. Povedal som si, že Trac je síce cool, ale vôbec nie je určený na písanie blogu alebo vytváranie stránok. A prešiel som na WordPress. Chvíľku mi dal zabrať súboj s mojím predsudkom, že z PHP nič dobré nemôže vyrásť. Veru z PHP môžu vyrásť veľmi pekné a užitočné veci. Jediný problém je v tom, že v halde iných vecí, ktoré nie sú až tak dobré, sa to dobré proste stratí.

Svoje pocity, zo zúfalého kolečka vyššie popísaného šialenstva, som pretavil do niekoľkých článkov o vzoroch správania v projektoch. Štruktúra a obsah bol inšpirovaný knihou Adrenaline Junkies and Template Zombies.

21. 6. 2009 Hosting WordPressu som následne vyladil do stavu, kedy nahodenie nového WordPressu aj s frizúrou zabralo len pár okamihov.

27.6. 2009 Inšpirovaný Kabátmi som prerobil začiatok ich pesničky na: “Když něco rozeberem, tak leda debuggerem.” Kde som sa snažil naznačiť, že používanie debuggeru je dobré a bezbolestné. A vývojári, čo vedia zložiť viac než Lego, by ho mali používať.

3.7. 2009 Prednášal som v Žiline o projekte na spracovanie máp – Maptiler. A okrem iného padol geocaching.com.

17.7. 2009 Padol Stronghold a bola zrušená jedna zbytočná kancelária. Tento krok bol náročný, ale veľmi dôležitý, aby mohli nastať ďalšie zmeny.

19.8.2009 Geocaching.com už bežal a podarilo sa mi umiestniť svoju prvú kešku.

20.9.2009 Pridal som zálohovanie k poskytovaným službám.

21.9.2009 FP-40. Nie, to nie je názov tajnej zbrane. Toho dňa som spustil Kampaň za podporu písania diakritiky vo FlashPlayeri pod Linuxom. Vyzeralo to nevalne. Problém dlho neriešený a ignorovaný. A div sa svete! Úspech sa dostavil 17.11. 2009.

23.9.2009 Dozrel konečne článok o Ticket systémoch a ich účinkoch na komunikáciu s klientmi.

28.9.2009 FreeBSD ma už zas vytočilo. Aj napriek veľkej snahe porozumieť princípom a neuveriteľnému množstvu času venovaného upgradom a kompiláciam, sa mi nepodarilo upgradnúť jeden smiešny kritický balík. Tým spečatilo FreeBSD svoj osud na niekoľkých serveroch.

16.10.2009 Prednášal som na WebExpo 2009 – Když něco rozeberem, tak leda debuggerem. Prednáška sa mi veľmi páčila a mal som z nej dobrý pocit. Hlavne vďaka super publiku.

30.10.2009 Napísal som článok: Štartuje vám Windows pomalšie a pomalšie? Ľahká pomoc! Tento článok sa stal najnavštevovanejším článkom roku 2009.

26.11.2009 Zase som narazil na to, že si niekto zvolil dočasné riešenie vo vidine ušetrenia prostriedkov. Tak som to pretavil do článku. ;-)

28.11.2009 Pridal som Plone k technológiám, pre ktoré poskytujem hosting. Hostoval som Plone portály už veľmi dlho, ale akosi nebol čas dať o tom vedieť verejne.

7.12. 2009 Prednášal som na FI MUNI o C++. Zaktualizoval som prednášku, pridal som informácie o nových trendoch.

16.12. 2009 Games for Linux som prehodil na WordPress. Pretože administračné rozhranie z mojej bakalárky od Medvedb, už nebolo príliš up-to-date.

17.12. 2009 Prednášal som v Žiline o technológiách Web 2.0. Hlavne o testovaní, potom o Flexe, niečo málo o Google App Engine a na záver pribudol aj Amazon Web Services.

26.12.2009 Podarilo sa mi pomocou Flixelu a Flexu vytvoriť malú jednoduchú hru.

31.12.2009 FlexGarden.net som prehodil z Tracu na WordPress a pridal som sekciu Flex v praxi.

Takže toľko výber toho najzaujímavejšieho za rok 2009. Ďakujem všetkým priznivcom tohoto blogu za komentáre a postrehy. :-)

26. November 2009

Dočasné riešenie je nebezpečné, drahé a trvalé

“No, tunak, šak sprav to hentak, to bude dobré. Šak potom to spravíme lepšie. To je dočasné riešenie.”

Koniec.

Videli ste už dočasné riešenie, ktoré by nepretrvalo veky?

Už niekoľko krát som narazil na efekt “dočasného riešenia”. Dočasné riešenie je nebezpečné, drahé a trvalé. Prečo?

Ok, takže máme problém. Z radiátoru nám kvapká voda. Ako ho budeme riešiť? Zoberieme kelímok od jogurtu, šup to pod radiátor a je vyriešené. Občas vodu vylejeme. Pohoda, klídek, tabáček. Môžeme si pogratulovať k lacnému, rýchlemu a kvalitnému riešeniu. Podarilo sa nám dokonca prekabátiť aj diablov trojuholník a máme splnené všetky tri faktory naraz. Super!

Ha. Odídeme na dovolenku a na kelímok zabudneme. Čo sa stane? No, pretečie. Naviac otvor v radiátore sa zväčší a celý vykurovací systém sa začne pomaly presúvať k susedom o podlažie nižšie. Oh, aké prekvapenie?

V softvérárčine sú dočasné riešenia ešte nebezpečnejšie. Manažér potrebuje riešenie. Keďže dnes sú všetci bizi, všetko musí byť hneď, zvolí rýchlo riešenie. Zvolí jednoduché “dočasné” riešenie, veď v budúcnosti sa nahradí lepším. A je vytešený z toho, ako múdro to vymyslel.

Lenže implementácia dobrého riešenia sa týmto predražila asi 10 násobne. Prečo?

Na odstránenie dočasného riešenia a nahradenie ho dobrým, potrebujete OBROVSKÉ množstvo úsilia, prostriedkov a odvahy. Jednak implementácia dočasného riešenia, získala vysoký moment hybnosti. Je v prevádzke spolu s fungujúcim systémom. To znamená, že na odstránenie dočasného riešenia musíte zastaviť celý systém. Rozanalyzovať ho, ako funguje. Dočasné riešenie samozrejme nie je dokumentované. ako hovorí ľudová slovesnosť: “Vývojári odchádzajú, kód zostáva.” Ďalej musíte navrhnúť nové riešenie, ktoré bude lepšie. Naimplementovať ho do systému a ladiť nepredstaviteľné množstvo problémov, ktoré vznikne vďaka tomu, že nad dočasným riešením začalo kopec ľudí stavať svoje riešenie.

No a diablov trojuholník si zoberie milého naivného manažéra do pekla a s celým jeho riešením.

Takže milé deti. Keď raz budete mať nutkanie implementovať dočasné riešenie vo vidine kľudných a pokojných zajtrajškov, dajte si pauzu. Zoberte si pero a papier a spočítajte si, koľko vás bude skutočne stáť.

23. September 2009

Vzor: Hrach alebo akoby tickety na stenu hádzal

Skúsili ste niekedy hodiť na stenu chleba s maslom alebo parenú buchtu? Čo sa stane? Prilepí sa. Na stene zostane minimálne fľak. Zopakujme celý experiment so sušeným hrachom. Zoberieme za hrsť sušeného hrachu, mávneme rukou a hodíme hrach o stenu.

S údivom môžeme sledovať výsledok experimentu. Sušený hrach sa od steny odráža. Na stene nezostáva prilepený. Akoby hrach na stenu hádzal.

Čo to má spoločné so softvérom? Veľmi veľa. Softvér obsahuje chyby a obsahuje ich veľa. Nemusí sa jednať o chybu štýlu, že sa vám v bankovom systéme odčítajú dva výbery z bankomatu namiesto jedného. Ale napríklad o nepríjemnú “chybu”, kedy musíte 10x kliknúť na okienko a potom sa otočiť na kolieskovej stoličke a v pravý moment stlačiť enter.

Čo s takýmito chybami? Vačšinou je dobré ich oznámiť autorom, aby ich odstránili. Takže sa pripravme na hod. Uchopíme problém. Rozoženieme sa. A hádžeme.

Problém dopadne do ticket systému, ktorý ho dostatočne spomalí, aby nešťastných vývojárov nezhodil zo stoličky a nepriklincoval o stenu. V ticket systéme zostane problém hybernovaný a uchovávaný len s malým množstvom pôvodnej energie. Pôvodná energia mohla byť skutočne ohromujúca, niekedy pripomínajúca výbuch sopky. Len namiesto kamenných bômb, padajú veľmi ťažké nadávky.

Ako vidíme, obranný účinok ticket systému je úžasný. Niektoré tickety sú preradené do sekcie vyhnívacia nádrž a po roku sú zmazané, ako nerelevantné.

A čo s tým robiť? Prečo ticket nie je vyriešený včas? Jednoducho preto, že nie sú dostatočné sily a manažment nevidí v tickete dostatočnú dôležitosť, aby preorganizovával vývojárov. Často tieto tickety znamenajú opravu 1-2 riadkov kódu. Čo je však podstatnejšie, 1-2 dni času vývojára. Na konci mesiaca už len zostane otázka: a kto to zaplatí?

Tak si ticket zostáva naďalej pekne hybernovaný a možno jedného dňa bude vyriešený. Poznám tickety, ktoré by už mohli chodiť aj do škôlky. Jednak majú na to vek a naviac už dorástli do slušnej veľkosti, tým ako si ich vývojári medzi sebou prehadzovali a pridávali komentáre.

Seriózne, čo sa s tým dá robiť? Zo strany klienta, je dôležité, aby si uvedomil, že proti nemu stojí ticket systém, cez ktorý musí jeho problém prebublať. Namiesto zvyšovania energie problému útočným a inzultatívnym tónom, radšej použiť asertívnejší prístup. Nakoniec, je dôležitá spolupráca a nie je dobré hodiť všetko na hlavu nešťastných vývojárov.

Zo strany dodávateľa softvéru je dôležité prehodnotenie priorít a namiesto sypania 30 nových vlastností za týždeň, vysypať len jednu. Zbytok úsilia venovať tomu, čo ľudí páli. Toto rozhodne nie je triviálna plánovacia úloha. Môže sa stať, že ticket je v rozpore so samotnou podstatou systému a musí byť zvolené úplne iné riešenie.

Softvér nie je vec, ktorú si kúpite v obchode a zavesíte nad kuchynskú linku. Samozrejme, že softvér, za ktorým je množstvo kvalitnej práce, sa takto môže javiť. Na kvalitný softvér je potrebná rozumná spolupráca oboch strán. Ako dodávateľa, tak odberateľa.

25. June 2009

Vizualizácia kódu

Zorientovať sa vo veľkých softvérových projektoch, ktoré človek doteraz nevidel a žil v šťastnej nevedomosit o ich existencii, nie je vôbec jednoduchá úloha. Vo veľkom projekte sa môže stratiť nie len náhodný cudzinec, ale aj príslušníci kmeňa vývojárov, ktorý sa o projekt starajú. No a z hlavného architekta sa stane kmeňový šaman, veštiaci architektúru z rozhádzaných kostí. Pri projektoch, ktoré rastú a rozvíjajú sa, môže tento problém nastať veľmi rýchlo.

Na pomoc s orientáciou v kóde sa používa vizualizácia pomocou diagramov a schém. Prvý nápad ako vizualizovať kód napríklad C++ servera je nakreslenie tried do UML. Pokiaľ má projekt niekoľko stoviek až tisícok súborov so zdrojovým kódom, nie je to veľmi šťastný nápad. Existujú nástroje, ktoré vám pomocou Reverse engineeringu zostavia UML schému.

UML je síce pekné, ale takéto zobrazenie nemá takmer žiadnu vyjadrovaciu silu. Dôležité informácie zapadnú v kvante ďalších informácií a k reverse engineeringu musíte pripojit steganografiu a datamining.

Existujú projekty, ktoré vedia zanalyzovať kód a vytiahnuť z neho veľmi zaujímavé informácie. Pokiaľ sa pohybujeme v dvojrozmernom svete, tak stojí za to zmieniť dva z nich.

CodeCrawler prehľadáva kód a zobrazuje ho vo forme jednoduchého grafu. Projekt je určený primárne pre Scheme.

Zaujímavjším je projekt X-Ray. Jedná sa o plugin do Eclipse. Analýza je omnoho interaktívnejšia, takže priamo v prostredí IDE, je vývojár schopný vidieť, kde sa mu v projekte vytvárajú príliš veľké triedy alebo God objekty.

Tu len pripojím malú poznámku: god objekt v projekte, je ten, ktorý toho vie príliš veľa a robí príliš veľa. Typicky vzniká postupnou kumuláciu funkcií v singletonoch. Jedná sa o antipattern.

Trojrozmerný svet prináša novú dimenziu :) Pomocou nástroja CodeCity je možné kód vizualizovať vo forme mesta. Na základe relatívne jednoduchej vizualizácie dokážete  v kóde identifikovať “budovy”, ktoré sú príliš veľké alebo tenké a vysoké. Tieto krajné prípady predstavujú zdroj potenciálnych problémov pri ďalšom vývoji.

Argo UML v024-coarse

Dobrý podcast na tému vizualizácia kódu nájdete na stránkach Software Engineering Radio.

17. June 2009

Vzor: Prekvapenie!

Náročný projekt. Na všetkých je kladená vysoká záťaž. Tu dostane manažér nápad, že by bolo dobré zdvihnúť motiváciu ľudí. Tak zvolá všetok pospolitý ľud z projektu. Ľud preruší debuggovanie, vystavovanie faktúr, konzultácie s klientami, prácu na dátových poliach a húfne sa prihrnie do míting rúmu.

Projektový ľud diskutuje, čo sa bude diať. Zvyšovať platy? Prepúšťať? Všetko je možné.

Vtom vstúpi sám veľký manažér a asistentka za ním nesie nejakú krabicu.

“Drahí účastníci projektu. Pracujete tvrdo a preto sme sa My Manažment rozhodli odmeniť tých najschopnejších z Vás.”, manažér vystrúha 1.5 kW americký úsmev.

Začne vyvolávať mená ľudí. Ľudia postupne chodia a berú z rúk manažmentu cetky ako USB kľúče, dáždniky, poukážku na obed v reštaurácii.

Bolo “odmenených” cca 30 ľudí z celej pospolitosti projektového ľudu, čítajúceho 100vku osôb.

Myslíte si, že sa týmto podarilo manažérovi zlepšiť atmosféru?

Nie, nepodarilo. Pretože ľudia, čo dostali USB cetky, dáždnik cetky sa cítia podvedený. Do projektu vložili hodiny svojho času, pracovali vo voľnom čase, bez nároku na preplatenie hodín, aby projekt dokončili. Cetku od manažmentu vnímajú ako lacný trik, ktorým si ich chce kúpiť.

Chlapík, čo dostal poukážku na obed pre dvoch, sa po skončení mítingu zastaví za sekretárkou a vracia jej poukážku so slovami: “Keby som prišiel za manželkou s touto poukážkou ako odmenou za všetky nadčasy a víkendy, čo som strávil na projekte, tak ma zastrelí. Zoberte si to.”

Ľudia, čo nedostali nič sa cítia dotknutý, že manažment nedokázal rozpoznať ich prácu a znechutene odchádzajú debuggovať a vymáhať nezaplatené faktúry od klientov.

Takže manažérovi sa Prekvapením podarilo dosiahnuť úplne opačnú reakciu než chcel.

Tento vzor je pekne popísaný aj v knihe Adrenaline Junkies and Template Zombies, ako vzor Surprise!

Čo dodať? “Prekvapenie!” rozhodne nie je príjemný zážitok. Preto dajte pozor na to, akým spôsobom odmeňujete ľudí vo vašom projekte. Aby Prekvapenie, nebolo Prekvapením pre vás.

8. June 2009

Vzor: Mobilový manažér

Ako ho spoznáte? Jednoducho, porovnáte ho proti nasledovnému checklistu:

  • nevie používať Google
  • nevie používať hlavu a veľmi aktívne sa vyhýba mysleniu
  • vie používať mobil a ten používa ako kompenzáciu predchádzajúcich dvoch bodov
  • telefonuje tak, aby všetci počuli jeho superdôležitý telefonát

Toto nie je vôbec vtipný vzor, aj keď sa na prvý pohľad môže tak javiť. Je to závažný antipattern a vo svojej najhoršej podobe môže pôsobiť ako silný demotívátor ľudí v tíme.

Dnes je každý manažér. Či už je to manažér pre obchod alebo pre predaj suchých rožkov, každý je proste manažér. Vy ešte nie ste? Ale no, prehnaná skronosť sa vám nehodí. Určite ste manažérmi. Minimálne ste hlavný CEO a CIO pre svoj voľný čas.

Predstavme si, takú dobrú, fungujúcu skupinku manažérov. Manažér pre zdrojový kód píše aplikáciu a spolu s manažérom pre opravú chýb ju vyladzujú. Manažérka pre web design im dodá css a všetci sú šťastný. V tom hlavný šéf dostane skvelý nápad. Má k dispozícii nezaradeného manažéra Avokádo a potrebuje mu prideliť nejakú robotu. Naša spokojná skupinka manažérov si pracuje na produkte a ešte netušia, čo sa stane.

Šéf dostane nápad (aj šéfovi sa občas niečo také môže podariť): priradí manažéra Avokádo na projekt k našej šťastnej skupinke. Avokádo je však mobilový manažér. Namiesto Googlu a svojej hlavy začne používať mobil. No a náš skvelý spokojný tím, sa stane zrazu nespokojným. Stále musia Avokádovi všetko vysvetľovať. Šéf je spokojný, Avokádo stále telefonuje a je BIZZY a rieši problémy. To, že zbytok produktívneho tímu je na prášky je druhá vec.

Ak ste ho už stretli. Alebo mali ste tú smolu s ním pracovať, napíšte, ako sa vám podarilo spluprácu vyriešiť. ;)

6. June 2009

Vzor: (Re)Inštalatér

“Nóóo, ono mi to zas nejde.”

“Čo?”

“Už som to desať krát preinštaloval a stále to hlási: doinštalujte ovladač pre import ružových sloníkov.”

“A nebolo by lepšie tam ten ovladač nainštalovať?”

“Áaale, ja som už skúšal modrých a žltých sloníkov a nejak sa pobili, tak som preinštaloval celý systém.”

“A?”

“Nefunguje to.”

“Hm. A čo tak preinštalovať celý dom.”

“Vidíš, to ma nenapadlo. Idem pohľadať inštalačné CD.”

Reinštalatér je ďalší antipattern (anti-vzor), s ktorým sa v IT praxi bežne stretnete. Do istej miery sa podobá vzoru Reštartér. Reinštalatér spotrebuje enormné množstvo času v rôznych dialógoch, niekoľkonásobným sťahovaním toho istého updatu alebo opravy.

Tento vzor sa typicky prejaví tam, kde osoba nemá dostatočné znalosti a dokonca ani netuší, že väčšina aj grafických inštalácií sa da plne automatizovať a veľa problémov sa dá vyriešiť aj bez preinštalovania. Preinštalovanie ako také väčšinou problém nerieši, skôr ho na určitú dobu oddiali.

Narozdiel od Reštartéra môžeme identifikovať určité prvky návykovosti. Pravý Reinštalatér sa cíti nesvoj, pokiaľ aspoň raz za deň nepreinštaluje nejaký program a raz zatýždeň celý systém.

Poďme sa pozrieť na opačný protipól a to sú možnosti automatickej inštalácie. Napríklad ja mám Linux Debian, ktorý som nainštaloval z Knoppixu, ešte roku 2003. Medzitým systém vymenil niekoľko hardvérov a niekoľko krát sa naklonoval na iné počítače pomocou rsyncu (kópia filesystému) a je tak vyladený, že nové inštalácie systémov sú proti tomu neohrabaný behemoti aj napriek tomu, že majú nové preblýskané KDE.

Ale nie len Linuxom je človek živý. Napríklad na Windows existujú skvelé nástroje ako Symantec Ghost. Človek vytvorí jeden image a ten potom len klonuje. No a skutočný úspora času prichádza s AI  Snapshot. Tento nástroj vie porovnať stavy počítača pred a po inštalácii a vytvoriť balíček, ktorý je možné pomocou Symantec Management Console distribupvať na klientské počítače. Takže taký OpenOffice človek nainštaluje len raz a potom ho deployne behom pár minút na 50 strojov. A určite existuje aj kvantum ďalších nástrojov na automatickú inštaláciu. Sem s nimi ;)

5. June 2009

Vzor: Reštartér

Deň 1.: Bolí vás zub.

Dáte si ibuprofén/ataralgin/nohy na stôl (*nehodiace sa škrtnite)

Deň 2.: Bolí vás zub.

Dáte si ibuprofén.

Deň 3. – ráno: bolí vás zub.

Dáte si ibuprofén.

Deň 3. – obed: bolí vás zub.

Dáte si ibuprofén.

Ehm, nemali by ste sa nad sebou zamyslieť? A napríklad vyriešiť problém tým, že zájdete k zubárovi?

Ako to vyzerá v prípade IT?

Ten …. systém zas nefunguje. Lup, reštart. Už zas to zatuhlo, lup, reštart. Ten server nefunguje, lup, reštart. Už zas nefunguje, lup, reštart.

Tak ako v prípade boľavého zubu nepomôže zvyšovanie dávky ibuprofénu, tak ani reštart nerieši príčinu problémov. Prvé náznaky módy reštartu môžeme badať už v DOSe, kde sa však jednalo len o chabé pokusy o zavedenie novej maniery. Skutočný zdokonalenie a dotiahnutie reštartovania ad absurdum priniesli až nasledujúce systémy Window.

Vzor chovania Reštartér je pandemický a nebezpečný. Vychádza z toho, že osoba nerozumie technike natoľko, aby našla správne riešenie a nemá sa ani koho spýtať. Preto siahne po zaručenom reštarte. To, že sa reštartom problém neodstráni, nevadí. Hlavne, že je zase chviľku kľud a všetko “funguje”.

Ak si Reštartér reštartuje dokola len svoj počítač, nie je to až také zjavné. Horšia je situácia, keď má takýto reštartér na starosti centrálny firemný server, ktorého štart trvá dobrých  päť minút. Typické situácie sú:

  • Nefunguje pošta? Reštart.
  • Nefunguje sieť? Reštart.
  • Nefunguje vysavač? Reštart.

Ako vidíte, Reštartérovi nezáleží na to, čo je skutočná príčina problému. Napríklad u vysávača asi nebude préblém v tom, že nevie získať IP adresu.

Ak ste u seba identifikovali príznaky Reštartéra nemusíte ešte hádzať klávesnicu do žita. Možno sa vám na prvý krát nepodarí odhaliť príčinu problému. Každopádne sa pri každom reštarte sa zamyslite a pokúste lokalizovať príčinu. Pretože pokiaľ nebude včas odhalená, je možné, že sa objaví ďalšia ešte zákernejšia príčina a navzájom sa budú maskovať.

  • Babel fish

      Translate from:

      Translate to:

  • Where’s the fish?

  • Further info

  • Badges

  • Video channel

  • Learning

    Grow your brain.
  • Tags

  • Topics

  • May 2013
    M T W T F S S
    « Feb    
     12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
  • Comments