Stala se nám takový nemilý, nepěkná věc. Do kódu se nám dostaly závislosti na knihovnách, které mají buď nestabilní nebo zastaralé API.
První je Apache HttpClient ve verzi 3. Prostě takhle jednoho dne přijdeme do práce a zjistíme, že máme v kódu spoustu závislostí na třídách jako je HttpMethod. Máme je samozřejmě pěkně izolované v jedné vrstvě aplikace, ale i tak je to na neuvěřitelném množství míst. Nevím jestli jste si všimli, ale je to opravdu HttpClient ve verzi 3. Dnes, v době, kdy je nová verze 4 už asi pět let na světě!
Druhá podobná věc se nám přihodila s Akkou. Do relativně důležitého API se nám dostala scala.concurrent.Future. A ano, opět čtete správně, není to Javovská java.util.concurrent.Future, je to cosi ze Scaly. Proč jsme něco takového dopustili? Asi z mladické nerozvážnosti. Prostě nám tenkrát nedošlo, že děláme blbost. Nemám nic proti Scale nebo Acce. Jde jen o to, že komunita kolem obou mírně řečeno kašle na zpětnou kompatibilitu. Takže jedeme na obstarožní verzi Akky, protože zkrátka nemáme dost času a odvahy na aktualizaci. Nejen že mají v nových verzích jiné API, ono se to celé i dost jinak chová.
Proč to tu vlastně píšu? Chci si pro příště vtlouci do hlavy toto:
Do důležitých API podezřelé třídy nepatří!
Otázka je, co jsou podezřelé třídy a jak se bez nich obejít? Podezřelá třída obvykle pochází z neustálené knihovny. Z takové, v které se často mění API nebo chování zpětně nekompatibilním způsobem. Je samozřejmě těžké předvídat budoucnost na základě minulosti, ale většinou to člověk pozná z release notes, uživatelského fóra nebo dokumentace. V obou našich případech to bylo evidentní. To, že už existuje nová, úplně jiná verze HttpClienta jsme věděli. To, že autoři Scaly ještě nepochopili, k čemu je dobrá zpětná kompatibilita, také není žádné tajemství.
Takže jak správně postupovat? Příště bych se nejdřív podíval, jestli neexistuje ekvivalent buď přímo v Javě nebo v nějaké prověřené knihovně jako je Spring. V našem případě jsme mohli použít abstrakci ze Springu. Ta by nás od API HttpClienta odizolovala. Mohli bychom se přepínat mezi implementacemi HTTP knihovny podle libosti. Stejně tak v případě Akky jsme mohli použít standardní Javovskou Future alespoň na úrovni API. Tím bychom si umožnili mnohem snazší update nebo dokonce změnu implementace.
No jo, ale co když neexistuje neexistuje žádná důvěryhodná abstrakce? Pak se musím se rozhodnout. Buď budu autorům knihovny věřit, že budou dodržovat zpětnou kompatibilitu. Také si musím být docela jist, že danou knihovnu nikdy nebudu chtít vyměnit za jinou. Nebo mi nezbyde nic jiného, a budu muset nedůvěryhodné třídy obalit do nějaké své abstrakce. A to tak, aby mi ta závislost nikudy neprosakovala. Vím, že je to na první pohled zbytečná práce. Vyhnete se ale tomu, co dříve nebo později čeká nás – bolestivému a zbytečnému přepisu hromady kódu.
Ze zkušeností víme, že cizí abstrakce jsou většinou nevyhovující abstrakcím naším. 🙂 Přesto nás lenost a neochota dělat věci opravdu pořádně svádí k jejich užívání.