Čistota návrhu - překrývání neabstraktních metod
Před nějakou dobou jsem narazil na knihu Java Nástroje. Z ní jsem vyčetl, že existuje něco jako statický analyzátor kódu. Od té chvíle jsem začal pracovat se CheckStyle a PMD. při nastavování pravidel jsem narazil na pravidlo, které říká něco ve smyslu: . dodržování tohoto pravidla v podstatě znamená, že není možné překrýt metodu, která není abstraktní.
Pro dodržování tohot pravidla hovoří mnoho především to, že máte jistotu, že ta implementace kterou čtete je přesně ta, která je nakonec používána. Je to osvobozující vědět, že chybu máte hledat přesně tady a ne v nějakém z dalších potomků této třídy. Protože se mi jeví jako nádherně přehledné v hierarchii mít vždy jen jedinou implementaci metody, začal jsem to dodržovat.
Aź dnes poprvé jsem narazil na porušení tohoto pravidla, kvůli, kterému musím procházet celou hierarchii tříd. Upravuju MVC Springu tak, aby můj controller byl více commandový a také více akční. Navážu tak jediný kontroler na více a mohu tam mít i více formulářů (třeba taková pošta je idealní příklad, kde se to hodí). Pří rozebírání třídy org.springframework.web.servlet.mvc.BaseCommandController jsem narazil na tři typy metod, které návrhář chtěl v budoucnu překrývat.
- První typ metody. Mimochodem jediný u kterého překrytí má smysl
(i když sporný) je metoda onAction. Jedná se o metudu, která je
volána ve chvíli když nastane nějaká akce.
- Druhý typ metody, jsem pro sebe nazval překrytím nastavitelný parametr. Jedná se o metodu, která vrací hodnotu například boolean, jejímž překrytím můžeme z hodnoty true, změnit parameter na hodnotu false apod.
- Třetím typem metody jsou metody funkční, které implementují vlastní logiku nějaké operace. Autor vytvořil nějakou jednoduchou implementaci operace a počítá s tím, že v případě potřeby ji uživatel překryje.
Nemůžu si pomoctm, ale překrývání z kteréhokoli z důvodů mi příjde jako . Na překrývání z prvního důvodu zná java technologii Listenerů. No, ale druhý a třetí typ překrývání mi přijde jako radikální zhovadilost. Při procházením zdrojákem nemáte naprosto tušení jakou hodnotu má parametr a kde ji dohledat, nebo s jakou implementací metody se aktuálně pracuje.
To že znáte dobře předka objektu který definuje metodu XYZ a také ji implementuje, ještě neznamená, že tam kde se právě používá se tahle metoda takhle chová. Je nutné propátrat úplně všechny předky a dokonce i potomky, jestli náhodou po cestě někdo nezměnil implementaci a vaše známá metoda nezměnila své chování.
P.S.: Pokud se mnou nesouhlasíte, zkuste napsat v kterých oblastech jsem nedohlédnul a jsem ještě zaslepen.