Category Archives: Knihovnička SE

Praktický API Design

Dnes budu psát o knize Practical API Design od Jaroslava Tulacha. Pomiňme její kvalitní zpracování, které se jen tak nevidí, zajímavý je obsah.

Na začátku je tam na můj vkus docela dost filozofování, ale možná to ke knize podobného zaměření patří. Zabývá se totiž pohledem na návrh API v Javě z trochu vyššího hlediska. To znamená, že se nebabrá v detailech, jako například správné pojmenování metod a rozdělení balíků. Kouká se na to víc shora. Tzn, jak dělat API tak, aby přežilo alespoň pár verzí. Dočtete se co dělat a co nedělat, na co si dát pozor. Autor se prostě pokusil o nemožné, zaznamenat na papír a předat své dlouholeté zkušenosti z návrhu NetBeans API.

Kromě toho je tam také hodně zajímavých myšlenek, které vás donutí se zamyslet. Třeba tvrzení, že krása kódu je věc sice pěkná, ale v podstatě neužitečná. Zní to jako samozřejmost, ale poprvé jsem to takhle natvrdo napsané uviděl až v této knize.

Nejvíc mě zaujala strana 173, která se zabývá tím, co o metodě řeknou její modifikátory. Tzn. věci jako public, final, abstract a podobně. To je věc, která mi do té doby nedošla. Pokud totiž chceme aby měla metoda jeden jediný účel, připadají v úvahu jedině následující kombinace:

  • public final – Metoda je tu k tomu aby ji někdo volal
  • protected abstract – metoda je to k tomu, aby ji někdo zastínil (naimplementoval)
  • protected final – metoda má být volaná podtřídami

Všechny ostatní kombinace, které obsahují public nebo protected mají víc významů, takže by se jim člověk měl vyhýbat. Například public se dá jak volat tak zastínit, takže není moc jasné, co je její správné použití. Jen pro úplnost upozorňuji, že private a (package) nás u API nezajímá.

A tady s dostáváme k věci, na kterou je třeba u knihy upozornit. Psal ji člověk, který se dlouhá léta zabývá návrhem API pro jiné programátory a to navíc pro Javu na desktopu a to ještě navíc v dynamickém prostředí, kde se moduly za běhu magicky načítají do paměti a zase se z ní vyhazují. Jeho styl myšlení a případy užití jsou tedy o hodně jiné než u mě. Já jsem zvyklý na serverovou Javu, která je zatím dost statická a navíc moji spotřebitelé jsou hlavně koncoví zákazníci. (více viz. v sesterském článku). Nejenže řeším úplně jiné problémy, některé rady jsou pro mě dokonce chybné!

Například stránka 221, kde autor řeší vzájemnou závislost listeneru a sledovaného objektu. Objekt v tomto případě drží odkazy na listenery a když se s ním něco stane, dá jim vědět. Autor tvrdí, že by objekt měl na své listenery odkazovat jen slabou (weak) referencí. Tak mohou být listenery uvolněny z paměti, když už nejsou potřeba, ale objekt samotný žije dál.

V případě NetBeans je to asi užitečná rada. K čemu držet v paměti listener, který sleduje změny v editačním okně, když leží v modulu, na který už se nikdo neodkazuje a tedy ho ani nepotřebuje. Tím, že editační okno drží na listener odkaz, znemožňuje odstranění celého modulu z paměti.

Když se ale na danou radu člověk podívá z mé serverové perspektivy, tak je to naprosto zvrhlé. Mám často listener, který na startu aplikace zaregistruji a pak už mě nezajímá. On dělá něco užitečného, může být třeba součástí složitého auditovacího modulu. Často je ten listener jediným pojítkem mezi daným modulem a zbytkem aplikace. Rozhodně nechci aby mi auditovací modul přestal fungovat, jen proto, že garbage collector uvolní listener z paměti. Tady vidíme, že rada která je naprosto legitmní pro NetBeans nemusí být platná pro server. Na to je potřeba dát pozor.

To je jen jeden aspekt. Navíc jsem přesvědčen, že „obyčejní“ programátoři jako já moc API nepíší. Původně jsem to chtěl na tomto místě víc rozebrat, ale věnuji tomu speciální článek.

Takže podle mého názoru je kniha hodně užitečná buď pro lidi, kteří opravdu píší knihovny, což není můj případ, nebo pro lidi kteří se rádi zamýšlí nad tím jak dělat software, což můj případ je. Je na vás, abyste se rozhodli, jestli do těchto skupin patříte. Pokud ano, rozhodně si ji nenechte ujít. Pokud ne, radši si znovu přečtěte Java Efektivně.

Nenuťte mě myslet

Nenuťte mě myslet (Do not make me think, Steve Krug) je kniha, na kterou často narazíte na stolech nebohých programátorů. A to i přesto, že se převážně zabývá použitelností webových stránek a ne aplikací. A jak tak koukám, tak to dokonce vyšlo i česky, pod názvem Nenuťte uživatele přemýšlet. Hmm, a dokonce jsou na internetu i recenze (1, 2, 3, 4). Tak si říkám, že nemá moc cenu, abych nosil dříví do Atén a přidával další recenzi.

Takže jen krátce: Mě se na knížce nejvíc líbilo, že se dobře čte, je relativně krátká a hlavně, že si při její četbě člověk hodně uvědomí o tom, jak se lidi na internetových stránkách chovají. Z pohledu programátora aplikací je asi nejužitečnější kapitola o uživatelských testech použitelnosti. Prostě o tom, jak zjišťovat, jak se potencionálnímu uživateli bude s naší stránkou a potažmo i aplikací pracovat. To je hodně zajímavé a užitečné. Takže dávám knize osm hvězdiček z deseti.

Java puzzlers

Tušíte správně, dneska vás čeká pidirecenze známé knihy Java Puzzlers od Joshuy Blocha a Neala Gaftera. Kniha obsahuje 95 krátkých hříček, rébusů a hádanek, které pěkně prozkouší vaši pozornost a znalosti temných zákoutí Javy.

Kniha je to zajímavá, člověk si toho hodně připomene, popřípadě naučí. Když má dost trpělivosti a nepřeskakuje rovnou na řešení, tak si může pěkně polámat hlavu. Schválně, kdo z vás by uhodl jak nadeklarovat i, tak aby byl následující cyklus nekonečný.

while (i==i+1){}

Řešení nebudu prozrazovat, nechám vám to za domácí úkol.

Nejen že jsem se u knihy pobavil, dokonce jsem se i naučil jeden docela užitečný trik. Je to řešení rébusu číslo 53.

Mějme třídu

public class Thing
{
	public Thing(int t){...}
	...
}

Implementujeme jejího potomka, v kterém potřebujeme spočítat nějakou hodnotu, tu si uložit a zároveň ji předat do konstruktoru předka. Tzn. potřebujeme udělat něco takového:

public class MyThing extends Thing
{
	private final int arg;
	public MyThing(){
		super(arg = SomeOtherClass.func());
	}
	...
}

Samozřejmě, návratová hodnota dané funkce se často mění a my potřebujeme aby naše řešení sneslo zátěž z více vláken. Zapoměl jsem se zmínit, že předchozí kód nejde zkompilovat, kompilátor vám vynadá, že nemůžete referencovat arg před tím, než zavoláte konstruktor předka.

Já vím, že vám je to naprosto jasné. Vzpomínám si ale, že jsem jednou narazil na podobný problém a nakonec jsem ho nevyřešil. Musel jsem to nějak obejít. A přitom je řešení tak snadné a elegantní. Tak co přijdete na něj sami?

public class MyThing extends Thing
{
	private final int arg;
	public MyThing(){
		this(SomeOtherClass.func());
	}
	private  MyThing(int i)
	{
		super(i);
		arg = i;
	}
	...
}

Docela užitečná finta.

Takže abych to shrnul, knížka je to zábavná i poučná. Naučíte se spoustu věcí o různých podivnostech v Javě. Na můj vkus je v knize trochu moc hádanek týkajících se různých celočíselných přetečení, zaokrouhlovacích chyb a podobně. To jsou podle mého názoru věci, s kterými se setkáte opravdu výjimečně. Ale i tak si myslím, že si kniha zaslouží sedm hvězdiček z deseti. Tomu kdo si chce počkat až to zfilmujou, doporučuji následující trailer.