Zkušenosti ze školního softwarového projektu BEEN
Úvod pro nematfyzáky
Součástí studia informatiky na MFF UK je i předmět Softwarový projekt. V rámci něj mají studenti za úkol vytvořit větší softwarové dílo, řádně ho zdokumentovat a obhájit před projektovou komisí. Cílem předmětu je především naučit studenty pracovat na větším projektu v týmu.
Při obhajobě jsou řešitelé vyzýváni, aby své zkušenosti z projektu sepsali a poslali projektové komisi – kvůli zpětné vazbě a poučení dalších generací studentů. Komise zkušenosti zveřejňuje na speciální stránce.
Rozhodl jsem se své zkušenosti zveřejnit ve svém zápisníku, protože mám pocit, že to je zajímavé téma nejen pro matfyzáky-informatiky a ukazuje to matfyz z trochu neobvyklé perspektivy. Nicméně text je i tak psán především pro "interní" čtenáře a komisi jsem na něj samozřejmě poslal odkaz.
Pro pořádek je nutno dodat, že náš projekt byl ještě veden podle starého systému – podle něj byla nominální délka projektu 1 rok a prodlužování bylo běžné. Dnes je už zaveden systém nový, kde je standardní délka projektu zkrácena na 9 měsíců a je omezena možnost prodlužování. Typický rozsah projektů by tedy měl být menší.
Obecné povídání
Po dokončení projektu jsem si říkal, že do zkušeností dost možná napíšu podobně ostrá slova jako kdysi Johanka. Od té doby jsem trochu vychladl, ale i tak moje zkušenosti rozhodně nebudou vyznívat pozitivně.
Celý projekt ve své současné podobě je šílenost. Jste hozeni do vody spolu s několika dalšími lidmi a místo aby vás někdo učil plavat, je na vás, abyste se neutopili a doplavali ke břehu. A tak se nějak plácáte a pokud se doplácáte na souš, stojí tam člověk (oponent), který víceméně subjektivně ohodnotí váš plavecký styl a může vás spolu s komisí poslat ještě si trochu zaplavat. Tak či onak na břeh vylezete vyčerpáni a nikdy v životě už do vody nebudete chtít vlézt.
O příčinách toho, proč projekty takto vypadají, už bylo napsáno mnoho. Jednou z příčin stávajícího stavu, o které se ale příliš nemluví, je neodbornost vedoucích projektů. Neodborností nemyslím, že by vedoucí nerozuměl tomu, co dělá (s tím jsem se na MFF téměř nesetkal), ale že nerozumí tomu, jak vést větší projekt srovnatelný s běžným komerčním. Není to nic překvapivého, protože 90 % lidí na MFF nikdy nic takového nedělalo – ale když někdo něco nedělá, neměl by to učit, ne?
Možná předchozí odstavce zní jako fňukání studentíka, že ho nikdo nevedl za ručičku. Jenže metoda "hoďme studenty do vody, ať plavou" zcela zjevně nefunguje (viz drtivá většina zkušeností z projektů). A byť je situace nyní aspoň částečně řešena (zkrácením doby k vypracování projektu a větším tlakem na včasné dokončení), je to podle mě málo.
Dle mého názoru by projekty ideálně měl vést někdo, kdo už někdy několik úspěšných (komerčních) projektů vedl, měl by studentům pomoci s metodologií, plánováním práce a dalšími organizačními věcmi. Aby se studenti naučili, jak se projekty mají dělat, a ne jak se dělat nemají.
Chápu, že takových lidí je minimum, nejsou peníze na jejích zaplacení a současní vedoucí mají milion jiných věcí na práci, než "managovat" studentské projekty, i kdyby to uměli. Ale co třeba kdyby měl předmět softwarový projekt na fakultě vyhrazeného člověka, který by právě s takovými věcmi studentům pomáhal? Za kterým by studenti přišli každé dva měsíce a on by jim dovedl říct, co dělají špatně a jak to dělat lépe? A neměl by na starost nic moc jiného, takže by se projektům mohl opravdu věnovat? Jen námět na zamyšlení...
A ještě si rýpnu: Učí se někde na matfyzu, jak připravovat srozumitelné prezentace a mluvit před lidmi? (Odpověď: Ne. Jediný předmět, který s tím měl něco společného – praktikum z informatiky – byl před několika lety bez náhrady zrušen.) Učí se někde na matfyzu, jak psát dokumentaci k programům? (Pokud je mi známo, tak taky ne, když nepočítám pár stručných tipů k dokumentaci zápočťáků, co se dají najít na webech vyučujících.) A proč se z toho tedy zkouší? A rovnou před komisí a s nezanedbatelnými negativními důsledky pro studium v případě neúspěchu?
O našem projektu
Teď trochu konkrétněji o našem projektu. Psali jsme prostředí pro spouštění distribuovaných benchmarků pro skupinu distribuovaných systémů na katedře softwarového inženýrství. Původní plán byl mít projekt hotový za cca 3/4 roku – to se nám podařilo přetáhnout téměř 3× (projekt se táhnul od podzimu 2004 do zimy 2006).
Při zpětném pohledu se zdá, že úloha nebyla nejlepším kandidátem na softwarový projekt. Bylo potřeba hodně zkoumat a vymýšlet architekturu celého řešení, a to se neobešlo bez mnoha slepých cest a přepisování už napsaných věcí. Softwarový projekt by měla být lépe ohraničená úloha. Na druhou stranu bylo výhodou, že vedoucí (Tomáš Kalibera) měl o projekt zájem a jeho přístup bych označil za vysoce nadprůměrný.
Klíčovým faktorem průběhu celého projektu byla absence jasné vedoucí osobnosti. Zpočátku to vypadalo, že se této role chopí Tomáš (vedoucí projektu), ale po cca 2–3 měsících polevil. Pak začal být aktivní Michal, který spolu s Jaroslavem vymýšlel architekturu projektu. V té době jsem si myslel, že kluci vědí, co dělají, a popravdě řečeno jsem se ani o samotné jádro projektu nechtěl příliš starat, takže jsem je nechal vymýšlet. Byla to chyba. Michal s Jarem strávili půl roku v nekonečných diskuzích, které nikam nevedly a projekt jen zdržely. Kdybych byl aktivnější a diskuzí se účastnil, možná bych je dokázal včas zarazit. Ale to je jen spekulace.
Projekt se v následujících měsících "tak nějak vyvíjel", ale někdy na jaře 2006 jsem získal pocit, že se nikam významně neposouvá, a postupně jsem se chopil "managování". Snažil jsem se řídit schůzky, evidovat a prioritizovat úkoly, apod. – zkrátka projekt trochu táhnout. Nebylo to lehké vzhledem k tomu, že jsem nepracoval přímo na jádru projektu (lecos pro mě byla "magie"), a vzhledem k absenci donucovacích prostředků. Myslím ale, že moje iniciativa v této době projektu výrazně pomohla. I tak jsem se dopustil nejméně dvou chyb:
- Příliš jsem věřil ostatním členům týmu a spoléhal na to, že se sami dokážou motivovat k práci. Zdaleka ne u každého to byla pravda – bohužel jsem některé členy týmu přecenil.
- Neinicioval jsem vyloučení Tondy Tomečka z týmu v létě 2006, kdy dva měsíce téměř nic nedělal. Bál jsem se, že převzetí jeho práce někým jiným by nás zdrželo. Dnes je jasné, že by to bylo naopak.
Antonín Tomeček, nejslabší článek týmu, je kapitola sama pro sebe. Zaslouží si, abych tu řekl, že jeho kód byl běžně dodávaný pozdě, byl špatně navržený i implementovaný a také plný chyb, což nám způsobilo nemálo problémů. Tonda se zbytkem týmu nesplynul ani lidsky, měl snahu se vyhýbat schůzkám a komunikace s ním nebyla snadná. Osobně ho nepovažuju za kompetentního programátora.
S blížícím se dokončením projektu se tempo prací zvyšovalo a velice dobře se poznalo, kdo ze členů týmu se v dřívějších fázích "ulejval" a kdo nikoliv. Spousta funkcí byla nakonec k mé nemalé radosti dodělávána na poslední chvíli nebo nebyla dodělána vůbec a z finální verze byla vyškrtnuta. Noc před odevzdáním jsme pracovali non-stop, což o projektu vypovídá víc než cokoliv jiného. (Byť je to u softwarových projektů na MFF běžné – což zas vypovídá o projektech jako celku.)
Co jsem se naučil?
V podstatě dvě věci:
- Javu a několik technologií okolo ní (RMI, Eclipse, Ant, Tomcat, JavaCC,...).
- Pochopil jsem, že lidi, se kterými budu někdy spolupracovat na čemkoliv důležitém, si musím vybrat sám, nejlépe na základě předchozích zkušeností na nějakém menším projektu. Zní to možná trochu namyšleně, ale z našeho týmu bych byl ochotný do budoucna spolupracovat jen s jedním, možná dvěma jeho členy. Ostatní mě nepřesvědčili buď po stránce programátorských schopností, nebo pracovní morálky.
Na dva roky práce, včetně posledních pěti měsíců permanentního stresu, kdy jsem v podstatě nežil a věnoval se jen projektu, to není nic moc.
Co jsem se naopak nenaučil, byla proklamovaná práce v týmu – práce v CZille (skupina dobrovolníků zabývajících se lokalizací a podporu produktů Mozilly v ČR) a Impala Design (webdesignerská firmička, kterou provozujeme s kamarádem) mi v tomhle dala mnohem víc zkušeností, už kvůli tomu, že se zde vše odehrávalo v reálném prostředí a ne všichni, se kterými jsem spolupracoval, byli matfyzáci.
Co bych doporučil dalším účastníkům projektů?
(Snažil jsem se vynechat věci, co už jsou mnohokrát řečeny jinde, krom některých opravdu důležitých.)
- Přečtěte zkušenosti z jiných obhájených projektů. Klidně všechny od A do Z. Bude vám to sice trvat dva dny (pokud to psychicky vydržíte a neutečete v průběhu čtení z matfyzu :-), ale budete mít šanci se vyhnout mnohým chybám. Čas, který pročtením zkušeností strávíte, se bohatě vrátí.
- Při zahájení zvolte metodiku. Některé projekty se dají
dobře naplánovat už na začátku, jiné, kde není vše zpočátku jasné, je potřeba
vyvíjet spíše iterativně.
My jsme se trochu pokoušeli o "big design up front", ale zpětně to byla chyba a měli jsme postupovat po menších krocích. Hodně kódu jsme kvůli špatně zvolené metodice přepisovali.
-
Každý kód by měl mít jasného vlastníka. Ten by měl rozhodovat o všem, co se v tomto kódu děje a krom triviálních případů (zjevné bugy, překlepy v komentářích, refaktorizace v jiné části projektu s dopadem na větší kus kódu) by měl být jediným autorem kódu dané části.
Speciálně by mělo mít jednoho vlastníka uživatelské rozhraní, je-li v projektu nějaké, a také dokumentace. Opak vede k nekonzistenci.
BEEN byl naštěstí přirozeně rozdělený do více samostatných částí, takže vlastnictví kódu fungovalo celkem samo. Části, které jednoznačného vlastníka neměly (např. některá rozhraní, která používali skoro všichni), byly po stránce kvality kódu asi nejhorší části projektu (krom kódu Tondy Tomečka, který mnohdy svou nekvalitou překonával veškerou představivost).
- Domluvte si společné kódovací standardy a dodržujte je. K
tomu není moc co dodat, snad jen to, že při nedodržování standardu je potřeba
s proviněným zacházet taktně (tj. ne mu přepsat soubor v CVS, ale upozornit
ho).
My jsme měli výhodu, že Java má standard od Sunu, který jsem prozřetelně doplnil dalšími konvencemi platnými pro nás. Pro Javu navíc existuje skvělý nástroj Checkstyle, který dodržování konvencí umožňuje kontrolovat.
- Mějte v týmu aspoň jednoho domain experta. Pokud většina
týmu nemá příliš znalostí z oblasti řešeného problému, nevadí. Ale alespoň
jeden člen musí být expert, aby rozhodoval architekturální věci a předvídal
problémy. Podobně by to mělo být i s implementačním jazykem – člen týmu,
který ho zná skrz naskrz, pomůže s řešením některých situací a především bude
znát knihovny, které vám mohou ušetřit moře práce.
V našem případě byl expertem na benchmarkování náš vedoucí. Michal Tomčányi se zas výborně vyznal v Javě a Eclipse.
- Hodně komunikujte. Dobrá věc jsou schůzky každý týden
– motivuje to k práci (každý řekne, co dělal minulý týden, přičemž "nic"
zní špatně) a ostatní získají přehled o celkovém stavu. Domluvené věci někde
zapisujte, ať nezapadnou.
My jsme schůzkovali celkem pravidelně, ale ze schůzek jsme si nevedli poctivé zápisy – každý měl jen svoje poznámky. Vědomosti tak byly roztroušené. Na větší věci jsme používali wiki (konkrétně DokuWiki), což můžu jen doporučit. Měli jsme také projektový mailing list, kde se ale spíš řešilo, kdo přijde a nepřijde na schůzku.
Velkou výhodou bylo, že čtyři ze šesti členů týmu jsme byli na koleji a mohli se tak sejít kdykoliv dle potřeby. Michal, který s námi nebydlel, ochotně přijížděl, když bylo potřeba. Zato Tonda fyzické vzdálenosti vyloženě zneužíval, na maily odpovídal pozdě, apod.
- Opatrně s angličtinou v dokumentaci a komentářích.
U nás byla angličtina součástí zadání. Sice jsme si angličtinu za dva roky dost procvičili, ale za cenu, že v dokumentaci i zdrojácích je pravděpodobně spousta chyb, které bychom v češtině neudělali. Naštěstí to náš oponent příliš neřešil.
A na závěr pár technických tipů:
- Pokud jen trochu můžete, nepoužívejte Javu na programování webových aplikací. Je staticky typovaná (kód je tak upovídaný a plný dlouhých deklarací), kompilovaná (zblázníte se z věčných restartů Tomcatu), špatně se v ní pracuje s řetězci (nemá regulární výrazy a s nimi spojené operace přímo jako součást jazyka) a nemá literály na základní datové typy (pole, asociativní pole, regulární výrazy), o pokročilejších věcech jako jsou uzávěry ani nemluvě. Lepší je nějaký skriptovací jazyk jako PHP, nebo ještě lépe Ruby nebo Python s frameworkem řešícím běžné úkoly (pro Ruby typicky Ruby on Rails, pro Python např. Django).
- Automaticky testujte vše, co testovat lze. Důležité jsou
jak nízkoúrovňové unit testy, testující jednotlivé třídy, tak funkcionální
testy, testující větší funkční celky. Tradičně obtížná oblast je testování
uživatelského rozhraní, ale i zde už začínají existovat použitelné nástroje.
Testy jsem psal v našem projektu prakticky jen já (z vlastní iniciativy). Na testování webového rozhraní jsem původně zkusil použít JWebUnit (nadstavba HTTPUnit), ale ukázal se nepoužitelný (kvůli nemožnosti rozumné interpretace JavaScriptu). Nakonec jsem našel nástroj Selenium Core, který funguje přímo ve webovém prohlížeči, a klikátko na generování testů Selenium IDE. Testy v Seleniu se ukázaly jako neocenitelné.
- Pokud nemáte vážný důvod pro opak, dokumentaci pište v textovém
editoru nějakého kancelářského balíku. Vážným důvodem je snad jedině
to, že velmi dobře ovládáte nějaký jiný nástroj na tvorbu dokumentace (TeX,
DocBook, apod.) a tvořili jste v něm už nějaký složitější dokument.
Jediná nevýhoda tohoto řešení je, že zdrojový soubor je binární a špatně se s
ním pracuje ve verzovacím systému (není možné zobrazit rozdíly mezi verzemi).
My jsme na dokumentaci použili OpenOffice.org a nemám k němu vůbec žádnou výtku – vše fungovalo perfektně. Problém s verzovacím systémem jsme vyřešili tak, že s výsledným souborem pracoval jen jeden člověk (já) a pro ostatní byl read-only. To nebylo vůbec na škodu, viz výše.