
Co je abstrakce

Vývojáři používají slovo "abstrakce" běžně, nicméně často s omezeným chápáním významu. Pro většinu, koncept abstrakce byl zastíněn jejím použitím v některých jazycích pro označení metody nebo třídy, která musí být děděna a přetížena. Stejně tak "použij abstrakci" pro spoustu developerů znamená "napiš abstraktní třídu".
Abstrakce je jednou z nejdůležitějších technik pro docílení decouplingu a stabilizaci veřejného rozhraní na všech úrovních.
Abstrakce: Způsob prezentace entity, který zachovává důležité atributy a skrývá implementační detaily. Abstrakce umožňuje správu komplexity.
Fajn, pěkný, ale co to znamená? Například slovo "auto" reprezentuje velmi dobrou abstrakci. Víte, co si po tím představit, víte, co má dělat. Na druhou stranu je za tím slovem schována velká variabilita implementace jednotlivých prvků.
A špatná abstrakce? "Plynový pedál", asi převzato z anglického "gas pedal". Specificky zmiňuje plyn, kolik takových aut jezdí? Většina je na benzín, další jsou na naftu, elektřinu, tak proč "plynový pedál"? Tato špatná abstrakce vznikla tím, že se do názvu dostal implementační detail. "Brzda" tím netrpí, technologie se mění, co brzda dělá zůstává stejné.
Příklady
/**
* Jednoduchý příklad
* --------------
* data monou být uložena do databáze, do souboru, poslána po síti...
*/
repository.saveToDatabase(item); // ❌ leaking
repository.save(item); // ✅ Nice
/**
* Auth příklad
* ------------
* user je autentifikován pomocí tokenu
*/
authModule.tokenExists(token); // ❌ leaking
/*
* Samotný stav "přihlášen" může vyžadovat více, než jen existenci tokenu
* - Token může existovat během registrace
* - Token může existovat během 2FA/MFA.
* Nicméně v těchto případech uživatel stále není finálně přihlášen
*/
authModule.isLoggedIn(token); // ✅ Nice
/**
* UI příklad
* ------------
* zkontrolovat, jestli uživatel kliknul na tab
*/
// ❌ leaking
const activeTab = tabs.find(tab => {
return (tab.left < X) && (tab.right > X) &&
(tab.top < Y) && (tab.bottom > Y)
}) ?? null;
// Předpokládáte, že záložky jsou obdélníkové
// ✅ Nice
const activeTab = tabs.getTabFromPoint({x: X, y: Y});
Pár pravidel
Podle čeho se rozhodnout, zda je abstrakce správná?
- Je v názvu "co to dělá" na místo "jak to dělá"?
- Můžete změnit implementaci bez toho, aniž byste museli měnit způsob použití?
- Pokud používáte cizí objekt, voláte jeho metodu místo zpracovávání jeho dat?
Pokud jste odpověděli "ano", pravděpodobně budete na správné cestě.