Vedeme lidské bytosti

June 21st, 2009

Mítinky jsou boje o moc mezi lidmi, kteří něco chtějí, a těmi, kteří jim to nechtějí dát.

Pravidelnější čtenáři tohoto nepravidelného blogu už jistě tuší, že je čeká další minirecenze. Tentokrát se jedná o knihu „Managing humans“ (na ten odkaz rozhodně klikněte) od Michaela Loopa (Jírovy patří dík za tip). Kniha je to stylem podobná Joel on Software a musím přiznat, že se mi líbila skoro stejně. Je sice o hodně méně technická, ale zato mnohem víc o lidech.

Dal bych ji za povinnou literaturu lidem, kteří se snaží vést (nebo nedejbože řídit) bandu nerdů. Ale je hodně zajímavá i pro nás nerdy samotné. Hodně užitečná je i pro lidi, kteří pracují v korporaci.

Takže co se v knize dočtete? Hodně mě zaujala kapitola o tom, jak uhodnout, co se děje na pracovní schůzce. Znáte to, sedíte na mítinku a přemýšlíte co tam sakra děláte, co a proč se ti lidé snaží říci. V kapitolách „Agenda detection“ a „Meeting creatures“ se to dočtete.

Zajímavé jsou i části, které popisují jak se připravit na pohovor, napsat životopis a podobně. To jsem měl sakra vědět před pár měsíci.

No a neméně zajímavé jsou i kapitoly o nerdech samotných. Například NADD. Ale třeba “Přiručka k nerdovi” se do knihy nedostala.

Jak jste si všimli, většina kapitol je volně ke čtení i na autorově blogu, ale mě se kniha čte mnohem lépe. Jenom si dovoluji upozornit, že je to psané pokročilejší angličtinou, takže se docela procvičíte. Například na straně 188 mě dostalo sloveso „to grok“, ale jelikož jsem nerd tak jsem to pochopil i bez slovníku. I když jak tak koukám, tak se to dostalo i do slovníků, zajímavé. Ale zpátky ke knize, ta zaslouženě dostává neuvěřitelných deset hvězdiček z deseti.

No a abych vás neochudil o tradiční ukázku z knihy, uvedu pár položek z vysvětlivek na konci knihy:

Agenda – Seznam věcí, které se musí na dané schůzce odehrát aby byla kompletní. Pokud všichni účastníci na dané schůzce nejsou seznámeni s agendou, bude docházet ke ztrátě času.

Spolupráce – Slovo používané k tomu, aby vás přesvědčili pracovat s lidmi, kterým byste se raději vyhnuli.

Milník (Milestone) – Chabě nadefinované, přehnaně vytrubované datum, které je částí softwarového vývoje. Vývojový tým při něm přemýšlí o tom jak je v pytli.

Proces – Šestipísmenné slovo začínající na P. Proces není špatná věc. Obzvlášť ve velkých organizacích kde ohromné množství lidí ztrácí velké množství času děláním té samé věci.

Specka (Specifikace) – Dokument, který říká jak to je. Proces psaní specifikace bývá víc užitečný než výsledný dokument.

Co že je to ten Wave?

May 31st, 2009

Včera jsem měl volnou chvilku, tak jsem se se zájmem podíval na hodinovou přednášku o Google Wave. Takže se cítím být natolik expertem, abych o tom něco napsal.

O co tedy jde? Těžko se to popisuje, je to něco mezi Gmailem, gTalkem, Facebookem, Picasou, Androidem a GoogleDocs. V zásadě se na to můžete dívat jako na nadopovaný gTalk. Základním stavebním prvkem je jedna Vlnka (wave). Je to podobné jednomu diskuznímu vláknu, v němž si můžete povídat s několika lidmi, okamžitě vidíte jejich odpovědi, můžete vytvářet soukromé poddiskuze, zkrátka nic světoborného. Co je převratné jsou způsoby rozšířitelnosti. Diskuze se například mohou účastnit roboti. Jeden robot vám třeba může v reálném čase opravovat pravopis, druhý vaši diskuzi může překládat do Klingonštiny, třetí může poznávat vložené odkazy. Roboty si můžete napsat sami za použití přiloženého API a pustit je třeba na Google App Enginu.

Samozřejmě si také můžete napsat vlastní rozšíření samotné Wave aplikace (Gadgets). Je to něco jako plugin do prohlížeče nebo vlastní Androidí aplikace, akorát v tomto případě běží na serveru (alespoň jsem to tak pochopil). Takže do Vlnky můžete kromě textu vložit i třeba šachovnici a zahrát si šachy.

No a jelikož to má všechno běžet na otevřeném a jednoduchém protokolu, nemělo by být problémem napsat si vlastní server. Dokonce tvrdili, že část kódu zveřejní jako open source. Když to shrnu, tak Wave je rozšířitelný chat. Rozšířitelný tak, že do něm můžete vkládat fotky, mapy, aktivní obsah, hry a v podstatě co skoro všechno co vás napadne. Pro podrobnosti si pusťte tu prezentaci, nudit se u ní rozhodně nebudete.

Dva druhy kódu

May 24th, 2009

Dnes budu zase psát o takové samozřejmosti, že ani nevím jestli s tím mám někoho obtěžovat. Navíc už jsem to před rokem předváděl na jedné konferenci. Možná ale nepatříte mezi těch deset šťastlivců, kteří mě tam viděli, tak to asi přeci jen napíšu. Začněme mojí oblíbenou ukázkou kódu:

public class PureJdbcBankDao implements Bank {
	public void setBalance(String accountNumber, BigDecimal balance) {
		Connection conn = null;
		PreparedStatement ps = null;
		try {
			conn = ConnectionFactory.getConnection();
			ps = conn.prepareStatement("UPDATE ACCOUNT SET BALANCE = ? WHERE ACCOUNT_NUMBER = ?");
			ps.setBigDecimal(1, balance);
			ps.setString(2, accountNumber);
			ps.execute();
		} catch (SQLException e) {
			throw new ApplicationException("JDBC failure", e);
		} finally {
			if (ps != null) {
				try {
					ps.close();
				} catch (SQLException e) {
					// what to do here?
				}
			}
			if (conn != null) {
				try {
					conn.close();
				} catch (SQLException e) {
					// what to do here?
				}
			}
		}

	}

Je to metoda pro zápis do databáze pomocí čistého JDBC. Toto je nádherná ukázka míchání dvou druhů kódu. Jednomu druhu říkám hezky česky „business kód”. To je kód, který je užitečný pro zákazníka. V našem příkladu po nás někdo chce, abychom změnili hodnotu v databázi. To obvykle děláme pomocí SQL příkazu, který vidím jenom na jednom řádku. Zbytek je „infrastrukturní kód”. Tak říkám kódu, který někdo udělat musí, ale zákazníkovi je v podstatě k ničemu. V našem příkladě to jsou všechny řádky kromě jednoho. Ano opravdu, zákazníkovi je naprosto jedno, že potřebuji připojení do databáze, je mu dokonce jedno, že ho musím po sobě zavřít, on po mě chce abych něco zapsal do databáze. Popravdě řečeno, často po mě nechce ani to, chce jen, aby jeho důležitá data byla dobře uložena.

Ale zpátky k věci. Když to přeformuluji tak mohu říci, že business kód je ten, co dělá něco zajímavého pro zákazníka, infrastrukturní kód je ten, který zajímá jen programátora. Samozřejmě potřebujeme oba druhy, je ale důležité si uvědomit který je který a přistupovat k nim rozdílně. Úplně nejdůležitější je držet oba druhy odděleně. Pokud máte JDBC kód v business vrstvě nebo nedej bože v kontroleru, tak vám nepomůže ani svěcená voda. Pokud ho máte schovaný v DAO vrstvě, tak jste v trochu lepší situaci. Ale i tak je obtížné takový moloch testovat a měnit. Představte si, že bych si vzpomněl, že potřebuji transakce. Musel bych upravit všechny metody v DAO vrstvě. To nezní jako dobrý nápad.
Existují i další argumenty proč infrastrukturní kód nepsat. Nejenže je takový kód nečitelný, on je navíc náchylný na chybu. Když náhodou zapomenu zavřít PreparedStatement nemusí to nějaký čas vadit. Po změně databáze ale můžu začít dostávat veselé chyby a může mi trvat pěkných pár dní než najdu jejich zdroj.

Já jsem obecně přesvědčen, že programátoři, kteří píší kód pro zákazníky, by se měli infrastrukturnímu kódu co nejvíce vyhýbat. Myslím si že je mnohem lepší psát kód takto:

public class JdbcBankDao extends SimpleJdbcDaoSupport implements Bank {

	public void setBalance(String accountNumber, BigDecimal balance)
	{
		getSimpleJdbcTemplate().
			update("UPDATE ACCOUNT SET BALANCE = ? WHERE ACCOUNT_NUMBER = ?", balance, accountNumber);
	}
}

Nejen, že rovnou vidím, co daná metoda dělá, já tam ani nemám moc co zkazit. Téměř všechen infrastrukturní kód zmizel. Samozřejmě že tam stále je, ale napsal ho za mě někdo jiný. V tomto případě autoři Springu. Ano mohl jsem si napsat vlastní framework, ale tím bych si moc práce neušetřil. Navíc bych do něj musel přidat podporu transakcí, podporu testování a podobně. Takže bych víc času strávil vývojem frameworku než něčím, co přináší zákazníkovi užitek.

Příklad s JDBC je samozřejmě trošku extrémní, málokdy se nám stane, že bychom motali JDBC kód s business kódem. Často ale vyvíjíme jiné typy infrastruktury a často nás ani nenapadne, že bychom to dělat neměli. Nebo nás to napadne, ale najdeme si nějakou výmluvu. Ze své praxe pamatuji několik případů, které jsem spáchal já nebo některý z mých kolegů.

  1. Asi nejčastější jsou všelijaké implementace vyrovnávací paměti (cache). Znáte to, máte číselníková nebo jiná málo se měnící data v databázi. Místo toho abyste je četli při každém dotazu tak si je přednačtete do mapy a pak je už jen taháte z paměti. Klasické míchání infrastrukturního a business kódu a také klasický kandidát na vlastní framework popřípadě knihovnu. Přitom stačí vhodně použít cache přes AOP (spring-modules nebo AOP cache).
  2. Načítání konfigurace je také oblíbené. S nástupem Springu už se s tím tak často nesetkáte, ale doby kdy si každý implementoval svoji variantu konfigurační knihovny neminuly zas tak dávno. Občas ještě v business kódu tu a tam zahlédnu načítání properties souboru a vytahování příslušné hodnoty.
  3. Logování je další klasický případ. Zde bych udělal výjimku z pravidla a řekl bych, že míchání logování a business kódu není na škodu, někdy může být i užitečné. Logy mohou pěkně zastupovat komentáře. Když ale říkám že logování samotné škodlivé není, psaní si vlastní knihovny na logování už škodlivé je. Myslím si, že zrovna logovacích knihoven máme v Javě dost.
  4. Skoro vždy se setkáme s vlastními utility třídami. Tedy třídami, které usnadňují věci, které v Javě nejsou zrovna jednoduché. Ať už se jedná o práci s časem a datem, kopírování input streamu do output streamu, načítání obsahu souboru do stringu a podobně. Ano, standardní knihovny jsou v tomto ohledu neohrabané, to ale neznamená, že si to musíme psát sami. Jakarta commons, Joda nebo i Spring nám v tomto ohledu rozhodně dokáží pomoci.
  5. Jednou jsem strávil krásný týden implementací skoro transparentního šifrování dat na úrovni Hibernate. Tzn. v Javě se s daty pracovalo normálně, ale i při ukládání a načítání do databáze se data automagicky šifrovala a dešifrovala. Měl jsem z toho projektu docela radost. Tu mi zkazily dvě věci. Týden po tom, co jsem to dopsal jsem zjistil, že už podobné řešení existuje. Druhou vadou na kráse bylo, že kolegové začali přes Hibernate dávkově zpracovávat desetitísíce záznamů a moje geniální knihovna na to nebyla stavěná a dost celé zpracování zpomalovala.
  6. Jsem si jist, že další příklady z praxe si doplníte sami.

Já jsem přesvědčen, že v dnešní době už člověk sežene knihovnu skoro na všechno. Pokud má to štěstí a knihovna mu umožní zbavit se infrastrukturního kódu, měl by ji použít. Pokud štěstí nemá a musí si opravdu napsat infrastrukturní kód, měl by ho důsledně oddělit od business kódu. Ale jak říkával kolega, každý, kdo se rozhodne napsat si vlastní knihovnu, by měl před tím desetkrát oběhnout barák, aby si to dobře rozmyslel. Ono to totiž není o tom ji jen napsat. Ono je potřeba ji zdokumentovat, otestovat, verzovat, donutit kolegy aby se ji naučili, dávat si pozor jestli máme dobře nadefinované API a spoustu dalších věcí.

Podle mě je jen jeden případ, kdy se vyplatí psát si vlastní knihovnu. A to v případě kdy do ní dávám kód specifický pro daného zákazníka. Například nějaké specifické výpočty, které chci sdílet mezi různými moduly, kód pro volání jeho backendu a podobně. Ale i tak je potřeba počítat s tím, že údržba takové knihovny zabere neuvěřitelné množství času a vaši kolegové z jejího používaní nebudou moc nadšení.

Takže abych to shrnul. Ať už píšete cokoliv, je dobré uvědomit si, který typ kódu to je. Pokud se jedná o business kód, tak je vše v pořádku. Pokud zrovna píšete infrastrukturní kód a není to hlavní náplní vaší práce (zdravím chlapce ze Sunu), zamyslete se nad tím, jestli je to opravdu potřeba. Zamyslete se jestli to už náhodou někdo nevyřešil za vás. Já vím, naučit se novou knihovnu je mnohem menší legrace než si ji napsat. Ale připomíná mi to jedno staré rčení, které říkalo něco v tom smyslu, že “Půl roku v laboratoři vás dokáže uchránit od deseti minut v knihovně.”