18. května 2008

Komentovat? Určitě ano.

Opět jsem se setkal s názorem, že komentovat zdrojové kódy není potřeba, že kód sám o sobě je dokumentace. K tomu můžu říci jen jedno - to je naprostá blbost.

Stačí nepracovat s vlastním kódem několik týdnů a už člověk ztrácí přehled o jemných detailech algoritmů, které sám psal. Nemluvě pak o tom, když je potřeba opravit chybu v rok staré aplikaci a nebo pracovat v kódu svých kolegů.

Také jsem slyšel "Jsem orientovaný na výkon a psaní komentářů mě brzdí". To je hodně krátkozraké, protože možná je člověk o pár minut rychlejší, když implementuje algoritmus, ale z dlouhodobějšího pohledu je to samozřejmě krátkozraké - čas strávený nad zjišťováním, jak jsem to já nebo můj kolega vlastně tehdy mysleli, je mnohem větší než kolik se dá ušetřit na jednom algoritmu bez komentářů. Ale já bych se vůbec do těchto polemik nepouštěl, protože dle mého názoru zdrojový kód se automaticky rovná kód plus komentáře.

Při psaní komentářů je potřeba nezapomínat, že zdrojové kódy nejsou Java soubory, ale také třeba konfigurační soubory, soubory prezentační vrstvy atd. To jsou také zdrojáky a ty je potřeba také komentovat.

Opačný extrém je takový, že na jeden řádek kódu připadají dva řádky komentáře. Není potřeba komentovat to, co je zřejmé z vlastního kódu. Zdrojový kód je jako dobrodružná knížka, kde jazyk Java popisuje vlastní děj příběhu. Komentáře jsou pak dějová vysvětlení, aby se čtenář v jednotlivých zápletkách neztratil. Pokud je toho vysvětlování příliš na úkor vlastního děje, tak pak to asi moc záživná knížka nebude.

14. května 2008

Máte čas na unit testy?

Pokud bych si měl hned sám odpovědět, tak dle mého názoru moc času není. Není z jednoho hlavního důvodu a to jsou peníze resp. náklady plynoucí z času, který bude věnován psaní unit testů. Hned na začátku také musím dodat, že celý článek je o "normálních" jednorázových projektech, které nejsou nějak mission-critical. U vývoje produktu (tj. aplikace, kterou zabalím a pošlu zákazníkům nebo aplikace, kterou opakovaně dodávám) předpokládám, že bude prostor pro psaní testů mnohem větší.

Ještě jsem nedělal ve firmě, kde by se počítalo s tím, že N dní budu vyvíjet produkční kód a dalších N dní budu mít vyhrazeno na testování (pozn. píši to sice v pořadí produkční kód, testy, ale klidně je možné si představit přístup opačný - TDD). Takto to často prezentují agilní přístupy k vývoji softwaru, ale v praxi je dle mého názoru toto neuskutečnitelné, aspoň tedy v rámci projektového vývoje, protože poměr nákladů na psaní unit testů vs. přínosy z toho plynoucí nejsou zrovna moc pozitivní.

V žádném případě nejsem odpůrce psaní testů, ale realita mě nějak naučila se na tu problematiku dívat i z jiného pohledu než jen vývojářského. Vidím spoustu výhod ze psaní testů, zejména následující dva:

  • zajištění požadované kvality produkčního kódu
  • kvalitou se nemyslí jen kód bez chyb, ale i takové věci, jako kvalitní architektura aplikace, dobrá dekompozice problému apod. Pokud chci psát efektivně testy, tak pak potřebuji mít i dostatečně kvalitní produkční kód.

Samozřejmě bez testů to nejde, nedovedu si představit, že bych takto odevzdal aplikaci zákazníkovi. Ale na jaké testy se zaměřit, aby přínosy a náklady byly v rozumné rovnováze? Dle mých zkušeností jsem asi nejlepší poměr přínosy vs. náklady zaznamenal v těchto případech:
  • znovupoužitelný kus kódu (knihovna, modul)
  • stěžejní aplikační logika, např. jádro aplikace
  • doménové objekty - equals. Na to jsou již testy napsané, takže je jen použít. Přínos možná malý, ale ušetří spoustu času při hledání chyb s kolekcemi.
  • při použití ORM nástroje testovat základní CRUD operace nad objekty. Pro tyto účely jsem si napsal sérii testů, protože je to stejné pořád dokola a je dobré vědět, že práce s DB na té základní úrovni funguje jak má. Spíše je to testování ORM mapování jako celku, než jen samotného procesu ukládání dat do DB.

Naopak mám negativní zkušenost z Mock (jMock, EasyMock) testů servisních a jiných interních rozhraní v aplikaci. Přínosem určitě bylo to, že mi testy drží strukturu aplikace pohromadě, ale velkou nevýhodou byla ztráta flexibility - kdykoliv jsem provedl nějaký refaktoring, tak jsem musel měnit i tyto testy. Testy se musí měnit vždy s ohledem na změny produkčního kódu, ale v oblasti rozhraní se mění a přidává celkem hodně a dle mého názoru výhody nepřevažují nevýhody.

Speciální kapitolou je testování GUI. Již jsem se na toto téma jednou rozepsal, kde jsem porovnával nástroje pro unit testy GUI. Bohužel je dost často rychlejší tedy levnější nechat GUI testy provést manuálně, než testy vytvořit a testovat automaticky. Většina si hned asi v duchu řekne, že je to možná levnější během vývoje, ale z pohledu nasazení, údržby a podpory aplikace to už neplatí. Toto je asi pravda, ale těžko se to prosazuje v průběhu vývoje. Úplně nejlepší je zapojit do testování zákazníka. Snažíme se vyvíjet iteračním způsobem a vždy na konci každé iterace dáme hotovou část aplikace zákazníkovi, který to následně připomínkuje.

Mě by hodně zajímalo, zda můj pohled na věc odráží realitu současného vývoje aplikací nebo zda jsem mimo. Znám spoustu firem resp. kolegů, kteří ještě nenapsali ani čárku testovacího kódu, ale na druhé straně znám i firmy, kde se na testování klade velký důraz. Já bych sám rád testoval určitě více než doposud, ale ekonomické tlaky od obchodníků, projekt managerů a vedoucích mi to moc nedovolují.

17. dubna 2008

Porovnání webových frameworků

Včera jsem zkouknul zajímavou prezentaci, kde se autor snaží na základě svých zkušeností a z pohledu různých kritérií porovnat Java webové frameworky (JSF, Spring MVC, Stripes, Struts 2, Tapestry, Wicket).
Pokud si chce člověk udělat takový první názor a nechce si všechny ty frameworky zkoušet, tak mi ta prezentace přijde super.

15. dubna 2008

Výhody a nevýhody EJB

Dost často kolem sebe slyším při rozhovorech o vhodných technologiích pro určitý projekt, že použijeme EJB, tím se nedá nic zkazit. Je to prověřená technologie, je to dostatečně enterprise, je to standard, takže vlastně nejsou žádné důvody, proč to nepoužít.
Já si myslím, že těch nevýhod může být celkem hodně. V tomto článku bych rád některé nevýhody prezentoval:

  • Testovatelnost aplikace - pokud chci testovat EJB, tak potřebuji EJB kontejner. Sice existuje pěkná knihovna Jakarta Cactus, ale přeci jen to není tak přímočaré, jako když mám POJO. Nebo mohu použít Embedded EJB kontejner, popis zde.

  • Přenositelnost - myslím, že každý ocení, když někde vyvine aplikaci, kterou pak může nasadit na libovolný server tak jak je, bez nějaké další potřeby konfigurace aplikačního serveru. Obecně se dá říci, že kolečko develop-test-deploy je rychlejší u lightweight řešení než u řešení s EJB.

  • Rychlost spouštění - jakýkoliv server, který obsahuje něco více než čistý webový Java kontejner se mi bude spouštět pomaleji. A během vývoje takový server pouštím opravdu často. Ano, nepoužívané služby si mohu vypnout, ale pak je otázka, proč potřebuji plný J2EE server. Proto se mi moc líbí myšlenka profilů ve specifikaci J2EE 6.

  • Náklady na EJB server - samotný EJB server se sehnat nedá (nebo dá?) a pokud je tedy EJB (přesněji řečeno EJB kontejner) potřeba, člověk musí sáhnout po J2EE serveru. Jedna věc jsou náklady na pořízení serveru, druhá věc jsou náklady spojené s instalací a školením pro práci s J2EE serverem. Přeci jen vše je složitější než Tomcat :).


Některé nevýhody jsou více či méně významné, nutné je také brát velký posun od EJB 2.1 k EJB 3.0 (nevýhod EJB 2.1 je o dost více, ale ty zde neuvádím). Nechci, aby tento článek vyzněl, že nemám rád EJB, to není vůbec pravda. Já se jen snažím říci, že EJB ano, ale jen pro ten typ aplikací, kde je to opravdu potřeba, protože EJB je "heavyweight" technologie, což sebou přináší určité nevýhody. Typický příklad - pro webovou CRUD aplikaci nad jednou databází bych EJB nepoužíval.

Kromě nevýhod má řešení s EJB i spoustu výhod:
  • EJB je řešení pro distribuované aplikace, tj. aplikační logika nebo aplikační komponenty jsou umístěny na více serverech (nemyslím cluster) nebo aplikace má několik typů klientů včetně tlustého klienta.

  • EJB zjednodušuje psaní vícevláknových aplikací

  • EJB nabízí transakční kontejner, který umožňuje efektivní řešení transakcí přes více datových zdrojů

  • pokud je distribuovaná EJB aplikace dobře napsaná, tak lze docílit větší robustnosti a škálovatelnosti aplikace než když aplikace bude bez EJB umístěná na jednom serveru.


Výhod je tedy hodně, ale potřebuji nebo ocením toto vše pro mojí aplikaci? Pokud ne, tak EJB nepotřebuji a mohu využít výhod lightweight aplikací.

14. dubna 2008

Konkurenční přístup k datům - zamykací mechanismy, díl čtvrtý

Dnes bych rád popsal pesimistické offline zamykání. Tento poslední díl mého mini-seriálu o zamykacích mechanismech navazuje na předchozí tři díly (1, 2, 3).

Důvody, proč někdy nestačí online zamykací mechanismy jsem popsal v minulém díle, nyní se budu tedy hned věnovat samotnému pesimistickému zamykání.

Pesimistické offline zamykání

Tento typ zamykání se nám hodí zejména v takových případech užití, kde pravděpodobnost "střetu" je velká nebo následky velké. Jen pro úplnost dodávám, že se jedná o offline zamykání, protože jinak bychom mohli použít Pesimistické online zamykání.

Tento typ zamykání je řešen na aplikační úrovni aplikace a před jeho realizací je nutné si zodpovědět následující otázky:
  • Co je potřeba zamykat? Objekt, mapu objektů nebo bude stačit jen určitý atribut objektu? Může se hodit např. tento přístup od Martina Fowlera.

  • Kdy se data budou zamykat a odemykat?

  • Jaký typ zámku použiji? Použiji zámek pouze na zápis dat nebo i pro jejich čtení?

  • Jak budu identifikovat vlastníka zámku? Bude to HTTP Session ID nebo uživatelské ID nebo něco jiného?

  • Jak budu udržovat zámky? Bude mi stačit interní paměť nebo budu potřebovat databázi.

  • Jak budu uvolňovat zámky? Mám na mysli standardní případy, kdy někdo bude mít zamknutá data a odejde na oběd. Má se zámek po určité době automaticky uvolnit, dovolíme jiným uživatelům tento zámek získat?


Těch otázek není málo a od jejich odpovědí se odvyjí implementace. Znám dvě:
  • Centrální zamykací systém (lock manager). Tento způsob používám, protože se mi líbí, že je to neinvazivní způsob (nemusím měnit objekty, pouze kde potřebuji přidám LockManager), je to centralizované řešení a dle potřeby mohu zvolit implementace uložení zámků - paměť vs. databáze.

  • Ukládání zámků přímo v objektech. Ty objekty, které potřebuji zamykat vybavím speciálními atributy, abych poznal, že daný objekt je nebo není zamknutý.



Pozn.: Většinu informací, které jsem v této sérii článků prezentoval, jsem našel v knížce POJO in Facade.