Jak je to s tím technologickým dluhem?

Už dlouho jsem tu nevystavil takový ten klasický plkací článek, kde jen o něčem filozofuji. Kdysi jsem měl takové články v oblibě, tak jsem se rozhodl, že to s nimi zase zkusím.

Bude to reakce nebo spíš doplnění Dagiho článku Technologický dluh vs. Overengineering. Chci se k tomu vyjádřit, protože jsem asi jedním z důvodů, proč nad tímto tématem Dagi tak hloubá.

Samozřejmě nehloubá nad tím, jestli máme psát špagety kód nebo ne. Tam není co řešit. Špagety do produkčního kódu prostě nepatří. Tečka. Ale máme hromadu případu, kdy situace není tak černobílá.

Ať se nám to lépe představuje, předveďme si to na příkladu dvou naprosto imaginárních programátorů, kteří mají k programování trochu odlišný přístup. Programátor R. nad věcmi víc uvažuje, snaží se je dělat co nejlépe a nejčistěji. Programátor L. je více pragmatický a hlavní je pro něj jednoduchost a co nejméně práce. Je možná tak trochu líný.

Takže L. předvádí svůj úžasně napsaný minimalistický kód a R. mu říká: “Hmm, tady ten krásný kousek kódu by bylo pěkné vytáhnout do znovupoužitelného modulu, ať si i ostatní programátoři mohou užít výplodu tvé geniality“. A na to mu L., hrozící se další dřiny, odpovídá: „Chápu tvůj neskonalý obdiv k mému veledílu, ale bojím se, že tento modul stejně nikdo nebude potřebovat. Byla by to jen zbytečná práce navíc.“

Tak a teď bych vás chtěl poprosit, ať se zamyslíte kdo z nich má pravdu. Je lepší strávit nějaký čas vytahováním kódu do separátního modulu a tím zvyšovat komplexitu nebo je lepší držet kód méně čistý, ale jednodušší? Je lepší jednoduchý nebo znovupoužitelný kód? Nějaké nápady? Řešení?

Odpověď je samozřejmě klasická. Zní: „Přijde na to.“ Překvapivě totiž záleží hlavně na tom, jestli se ten modul opravdu použije ještě někde jinde nebo ne. Pokud ano, pak se ta práce vyplatila a vyhnuli jsme se duplikování kódu. Takže ten modul snížil technologický dluh.

Pokud ale ten modul bude opravdu použit jenom z toho jednoho místa, tak jsme to evidentně překombinovali a máme zbytečně složitý kód.

Fór je v tom, že dopředu často nevíme, o který případ se jedná. Jak zní můj oblíbený citát: “Je obtížné cokoliv předvídat, obzvláště pak budoucnost“. A to je zdroj té neshody. Jedna strana tvrdí, že ten modul můžeme vytvořit, až to bude potřeba. Druhá strana zase tuší, že když se to neudělá teď, tak už se k tomu nedostaneme nikdy. Jednou mají pravdu jedni, jindy zase ti druzí.

Neplatí to samozřejmě jen o modulech, ale i o většině ostatních programátorských fíglech. Takže vrstvení aplikace je dobré, ale jen pokud je opravdu potřeba. Webové služby jsou dobré, ale jen pokud jsou opravdu potřeba. ORM je dobré, ale jen pokud je opravdu potřeba … Je mi skoro trapné skončit takovou samozřejmostí, ale co se dá dělat.

Maven, Eclipse, WTP and project dependencies

If you are working with Maven, Eclipse and WTP, you can encounter different problems.

One of them is connected to project dependencies. Imagine that you have an in-house library A and a web application B that depends on A. Sometimes, when I run the webapp in a server using WTP, it can not find classes (or resources) from B. It’s quite confusing if you get a ClassNotFoundException even though the class is apparently there. It happens only if you are using m2eclipse extras. If you have different configuration this solution will not probably help you.

Ok, so you have m2extras and you are getting ClassNotFoundException. What next? You have to check file A/.settings/org.eclipse.wst.common.component (I use the Navigator View to access the file)

If you see something like this

<?xml version="1.0" encoding="UTF-8"?> 
<project-modules id="moduleCoreId" project-version="1.5.0"> 
  <wb-module deploy-name="module-a"> 
  <wb-resource deploy-path="/" source-path="/src"/> 
  </wb-module> 
</project-modules> 

you have found the issue. The source-path attribute is wrong. It’s necessary to set the value to /src/main/java. Sometimes the path is not just wrong, but it’s completely missing. In such case just add a new line with corresponding configuration and everything should work as expected.

K čemu je java.lang.Void

Dnes Dagi narazil v mém kódu na použití třídy java.lang.Void. Řekl jsem si, že se pochlubím i svým věrným čtenářům. Kdyby někdo z vás nevěděl, k čemu taková třída je, můžete si přečíst její JavaDoc.

The Void class is an uninstantiable placeholder class to hold a reference to the Class object representing the Java keyword void.

Jasné jako facka. Pravděpodobně se s tímto typem setkáte při reflexi. Ale mnohem důležitější je použití v generikách. Často totiž narazíte v knihovnách na callbacky, které předpokládají, že chcete vrátit nějakou hodnotu. Například Springovský ConnectionCallback, který vypadá takto

public interface ConnectionCallback<T> {
	T doInConnection(Connection con) throws SQLException, DataAccessException;
}

Je ale otázkou jak zvolit typ T, pokud nechcete nic vracet. A zde právě přichází ke slovu java.lang.Void. Můžu napsat například následující kód

template.execute(new ConnectionCallback<Void>() {
	@Override
	public Void doInConnection(Connection con) {
		//your code here
		//...
		return null;
	}
});

Krása nesmírná. Na první pohled je jasné, co se tam děje. Jenom škoda, že musím napsat ten return null.

V rámci objektivity musím přiznat, že to zas není tak důležité. Většinou se s podobným kódem potkáme u anonymních tříd, kde na tom návratovém typu zas tak nezáleží. Ale i tak je to takový pěkný detail, který se hodí znát.