Joel on Software

Joel on Software   Joel, szoftverekről

 

További "Joel on Software" cikkek magyar nyelven

További "Joel on Software" cikkek angol nyelven

E-mail a szerzőnek (angol nyelven)

 

A szivárgó absztrakciók törvénye


Szerző: Joel Spolsky
Fordította: Verók István
2002. november 11.

Van az Internet működésében egy darabka trükközés, aminek helyes működésére öntudatlanul is nap mint nap számítunk. Az egész hálózat egyik alapvető építőelemét jelentő TCP protokoll egyik részletéről van szó.

A TCP egy megbízható adatátviteli mód. Ez annyit jelent, hogy TCP-vel üzenetet küldve az meg is fog érkezni, épen és egészségesen.

Sok mindennek a TCP az alapja, így például az elektronikus levelezésnek és a weboldalak letöltésének is. A kelet-afrikai sötét ügyletekre invitáló összes színes-szagos-szélesvásznú villámlevél is a TCP megbízhatósága miatt jut el szinte nyomdai minőségben a szönyegbombázott célközönséghez. Khirály.

Létezik azonban egy -- IP néven ismert -- másik adatátviteli mód is, amely nem megbízható. Senki és semmi nem garantálja, hogy az elküldött adat meg is érkezik, de ha igen, ütközben akkor is történhetnek vele furcsaságok. Tucatnyi IP-üzenet elküldése után egyáltalán nem szabad meglepődni, ha azoknak csak a fele éri el az úticélt, egyesek nem pont a küldés sorrendjében, míg mások helyett teljesen váratlan üzenetek érkeznek, akár mondjuk simogatnivaló orángutánbébik képei, vagy egyszerűen csak egy halom -- tajvani spamből már ismert -- olvashatatlan zaj.

A darabka trükközés: a TCP az IP-re épül. Másképpen szólva, a TCP-nek csakis egy megbízhatatlan eszközt használva kell tudnia megbízható adatküldést elérnie.

A trükk működését a következő egyenértékű (bár kissé agyament) valós életbeli példa illusztrálja:

Tegyük fel, hogy a Broadwayről az egész országot autókkal átszelve kell színészeket juttatnunk Hollywoodba. A kocsik némelyikét útközben halálos baleset is érheti. Egyes színészek útközben annyira berúghatnak, hogy leborotválják az összes testszőrzetüket és rányomnak egy orrtetkót, ami persze szalonképtelenné teszi őket a hollywoodi munkára. Az sem elképzelhetetlen, hogy a sok különféle bejárt útvonal miatt a színészek az indulásitól eltérő sorrendben érkezzenek meg. Ebbe a felállásba robban be új képzeletbeli szolgáltatásunk, a Hollywood Express, ami szerződésben vállalja, hogy a színészek (a) megérkeznek, (b) sorrendben, (c) kifogástalan állapotban. A trükközés itt abban áll, hogy végső soron a Hollywood Express is a megszokott hosszú járatú autós közlekedésre van utalva. A Hollywood Express tehát érkezéskor megnézi, hogy minden színész elfogadható állapotban fut-e be, és ha nem, akkor inkább telefonon leszerződteti az adott színész egypetéjű ikertestvérét, aki a kedvünkért szintén autózik egyet. Ha a befutók rossz sorrendben jönnek, a Hollywood Express sorbaállítja őket. Ha a lakatlanabb vidékeken autózó színészek útját éppen elzárja egy lezuhant UFO, akkor minden arrajárót szépen csendben átirányítanak akadálytalanabb útvonalra, és a Hollywood Express nem is közli a külvilággal, hogy erre egyáltalán szükség volt. A kaliforniai filmrendezők szemszögéből a színészek talán a szokásosnál többet késnek, de az UFO-szerencsétlenség nem az ő asztaluk.

Nagyjából ennyi a TCP-trükk. A számítástechnika tudományában a bonyolultabb viselkedések ilyenféle egyszerűsítő elfedése absztrakció néven ismeretes. Mi több, a programozás során igen sok erőfeszítés megy el ilyen absztrakciók kialakítására. Vegyünk például egy stringeket implementáló könyvtárat. Ott is úgy szeretnénk tenni, mintha a számítógépek a számokkal megegyező könnyedséggel tudnának stringeket kezelni. Vagy nézzünk meg egy fájlrendszert. Ott is a merevlemezben forgó itt-ott felmágnesezett felületek helyett egy hierarchiába szervezett könyvtárakból és azokban elhelyezkedő, byte-okat tartalmazó fájlokból álló rendszert akarunk látni.

Térjünk csak vissza a TCP-hez. A fentebbi egyszerűsített elbeszélésben megengedtem magamnak egy kis szabadságot, ami miatt Olvasóim egy része bizonyosan megorrolt rám, és most magában füstölögve szid engem. Azt mondtam ugyanis, hogy a TCP garantálja az üzenetek megérkeztét. Nos, ez nem igaz. Ha a kedvenc házikígyó elrágta a számítógéphez vezető hálózati kábelt, és egyetlen IP csomag sem jut át, akkor ott a TCP sem tud mit tenni, és az üzenet nem ér célba. Ha sikerült valamilyen módon magunkra haragítani a céges rendszeradminisztrátort, és ő a gépünket egy túlterhelt hub-ra kötve áll bosszút, akkor az IP csomagoknak csak egy része jut át, és a TCP ugyan működik, de irgalmatlanul lassan.

Ezt hívom szivárgó absztrakciónak. A TCP megkísérli elfedni (absztrahálni) az alapjául szolgáló megbízhatatlan hálózatot, de néhanapján a hálózat átszivárog az absztrakción, és ilyenkor megérezzük az absztrakció révén nem teljesen elfedett hatásokat. Ez csak egy példa arra, amit A szivárgó absztrakciók törvényének neveztem el:

Minden nemtriviális absztrakció (bizonyos mértékig) szivárog.

 

 

Az absztrakciók csütörtököt is mondhatnak. Néha kicsit, néha nagyon. Szivárgások pedig vannak. A dolgok elromlanak. Absztrakciók használatával ennek esélye egyre nagyobb. Pár példa:

  • Akár egy egyszerű kétdimenziós tömbön iterálás is nagyságrendekkel eltérő teljesítménnyel jár, ha vízszintes helyett függőlegesen történik, "a fa szálirányára merőlegesen" -- az egyik irány nagyságrendekkel több laphibával jár, a laphibák pedig költségesek. Még az assembler-programozóknak is elvileg megengedett luxus a sík szerkezetű címtartomány használata, de a virtuális memória is egy absztrakció, ami laphibánál szivárog, és egyes memóriahozzáférések kiszolgálása másokénál jóval lassabb lesz.
  • Az adatbázis-lekérdező SQL nyelv elvileg eltakarja az adatbázis-hozzáférés fizikai lépéseit, hogy az ember inkább csak a kívánt eredmény definiálására koncentrálhasson, az adatbázis meg majd kitalálja az ehhez kellő lépéseket. Egyes SQL lekérdezések azonban több ezerszer lassabbak, mint más, logikailag ekvivalens lekérdezések. Egy híres példa: bizonyos SQL-szerverek jóval gyorsabbak, ha a lekérdezésben "where a=b and b=c and a=c" szerepel, mint ha csak "where a=b and b=c" állna ott, jóllehet az eredményül kapott adathalom ugyanaz. Elvileg nem kell az elérés részleteivel törődni, az eredmény leírása a fontos. Néha viszont az absztrakció szivárog és rettentő lassulást eredményez, ekkor viszont elő kell szedni a lekérdezés-tervező leírását, rá kell jönni a hibára, és meg kell találni a gyorsítás módját.
  • Habár az NFS, az SMB és hasonló hálózati fájlszerverek használatával távoli gépeken levő fájlok is "úgy kezelhetőek, mintha" helyiek lennének, az összeköttetés lelassulhat vagy megszakadhat, ekkor persze a fájlok már nem kezelhetők helyi fájlként, és erre külön programkóddal fel kell készülni. A "távoli fájl ugyanolyan, mint a helyi fájl" absztrakció szivárog. Unix-rendszergazdáknak biztosan ismerős a következő példa: ha a felhasználók saját könyvtárukat NFS-en át érik el (egy absztrakció), és egy .forward fájl révén minden levelezésüket átirányítják máshova (egy másik absztrakció), és új levél érkezésekor az NFS-szerver nem elérhető, akkor a .forward fájl hiánya miatt a levél nem megy tovább. Az absztrakció szivárgása miatt pár levél két szék közt a padlón végzi.
  • A C++ string-osztályainak célja az az illúzió, hogy a stringek is az elsőrendű adattípusok közé tartoznak. Megpróbálják elfedni, hogy a stringek valójában elég kemény diót jelentenek, és megpróbálnak úgy tenni, mintha csak az egészekhez hasonló elemi típusról lenne szó. Szinte minden C++ string-osztály átdefiniálja a + operátort, szabad tehát az út a s + "bar" kifejezés és társaik előtt. De a helyzet azért nem ilyen egyszerű. Olyan C++ string-osztály az egész világon nincs, amivel a "foo" + "bar" kifejezés is érvényes lenne, mivel C++-ban a stringkonstansok mindig char* típusúak, nem stringek. Az absztrakció úgy szivárog, hogy a nyelvvel egész egyszerűen nem lehet betömni. (Érdekes módon a C++ egész történelmi fejlődése kapcsolatba hozható a string-absztrakció hibáinak kijavítására tett újabb és újabb kísérletekkel. Hogy miért nem lehetett egyszerűen egy saját string-osztályt tenni a nyelvbe, arra kapásból nem tudnék válaszolni.)
  • Esőben sem lehet olyan gyorsan vezetni, mint száraz időben, legyenek bár a kocsiban ablaktörlők, fényszórók, tető és fűtés, mert elvileg ezek megvédenek az eső hatásaitól (absztrahálják az időjárást), de azért a kocsi megsiklása még nyugodtan előfordulhat, illetve a zuhogó eső erősen lecsökkentheti a látótávolságot is, az időjárást tehát nem lehet teljesen eltakarni -- megint a szivárgó absztrakciók. 

A szivárgó absztrakciók törvénye azért nagy gond, mert ennek értelmében az absztrakciók nem egyszerűsítik céljuk szerinti mértékben az életünket. Amikor valakit C++ programozásra okítok, jó lenne, ha egyáltalán nem kéne megtanítanom neki a char* és a mutató-aritmetika mélységeit. Jó lenne egyből az STL-stringekre ugrani. Előbb-utóbb azonban le fogja írni, hogy "foo" + "bar", annak minden lélegzetelállító következményével együtt, és akkor már muszáj lesz egy vargabetűt tenni vele a char* felé. Vagy egy OUT LPTSTR paraméterű Windows API-hívással fog szenvedni, és egészen addig nem tud kimászni a kátyúból, amíg át nem látja a char*, a mutatók, a Unicode, a wchar_t, illetve a TCHAR header-fájlok rejtelmeit, illetve a mindezekből szivárgó dolgokat.

Amikor COM-programozást tanítok, milyen egyszerű lenne az élet, ha elég lenne a Visual Studio varázslóira és kódgeneráló képességeire szorítkozni! Ha azonban valami nem a várakozás szerint működik, akkor halványlila fogalmuk nem lenne, hogy mi történt, hogy hogyan álljanak neki a hibakeresésnek, és hogyan javítsák ki. Bizony, meg kell tanítani az IUnknown-ok, CLSID-ek és ProgID-ek minden csínját-bínját ... ó, te jó ég!

Az ASP.NET tanításakor is egyszerűbb lenne annyival megelégedni, hogy a vezérlőelemekre duplán kattinva lehet hozzájuk a felhasználó kattintásakor a szerveren lefutó kódot írni. Az ASP.NET még a  HTML hiperhivatkozásra (<a>) és HTML gombra kattintás közti különbséget is elfedi. Ezzel persze előjön például az a gond, hogy a HTML-ben hiperhivatkozással nem lehet űrlapot elküldeni, csak gombbal. Az ASP.NET tervezői ezt egy pár sornyi JavaScript kóddal és a hiperhivatkozásra tett onclick eseménykezelő függvénnyel oldották meg. Ez az absztrakció viszont szivárog. Ha a felhasználó böngészőjében nem él a JavaScript, akkor az ASP.NET alkalmazás sem működik helyesen, és a sikeres javításhoz a programozónak muszáj átlátnia az ASP.NET-féle absztrakciót.

Új, világmegváltó, hiperszuper kódgeneráló eszközök megjelenésekor a szivárgó absztrakciók törvénye miatt lehet olyan véleményeket hallani, hogy "először kézzel érdemes megtanulni, aztán lehet a hiperszuper eszközzel időt spórolni." A valamit absztrahálni akaró kódgeneráló eszközök, mint minden absztrakció, szivárognak, és ez csak az absztrakció menetének és működésének megértésével kezelhető bolondbiztosan. Az absztrakciók tehát nagyon segítik a már megértett munkát, de kevéssé segítik a megértést.

Így aztán az egyre magasabb fejlettségű és absztrakciós szintű programozási eszközök megjelenésével a jó szakemberré válás paradox módon egyre nehezebb lesz.

Az első Micosoft-gyakornokságom alatt Macintoshon futó string-könyvtárakat írtam. Tipikus feladat volt például olyan strcat függvényt írni, amely az eredményül kapott string végére mutató mutatót ad vissza. Pár sornyi C kódban megírható. Csak a K&R, ez a C nyelvről szóló vékonyka könyv kellett hozzá.

Manapság a CityDesk fejlesztéséhez szükséges ismeretanyag része a Visual Basic, a COM, az ATL, a C++, az InnoSetup, az Internet Explorer belső mizériái, a reguláris kifejezések, a DOM, a HTML, a CSS, és az XML. Az ősi K&R-hez képest mindegyik magasszintű eszköz, de a K&R ismerete nélkül igen gyorsan ingoványba lépnék.

Tíz éve úgy hihettük, hogy mára az újabb programozási paradigmák igen meg fogják könnyíteni a kódolást. Az évek során megalkotott absztrakciókkal valóban tíz-tizenöt éve még hallatlannak gondolt szoftverfejlesztési komplexitást tudunk kezelni (grafikus felületek, hálózati programozás). S miközben e nagyszerű eszközökkel (pl. modern objektumorientált űrlapkezelő nyelvekkel) irdatlan mennyiségű munka végezhető el nagyon gyorsan, absztrakciós szivárgásokba ütközve viszont heteket is elvesztegethetünk a megoldáson. VB-programozási feladatra is nem érdemes csak egyszerű VB-programozót felvenni, mert a VB absztrakcióinak szivárgásakor teljesen aszfaltba fognak ragadni.

A szivárgó absztrakciók törvénye nagyon erősen húz vissza.



A fordítás alapjául szolgáló angol cikk címe: The Law of Leaky Abstractions  

Joel Spolsky a Fog Creek Software alapítója. A Fog Creek egy apró szoftvercég, székhelye New York City. Joel a Yale egyetemen végzett, majd programozóként és menedzserként dolgozott a Microsoftnál, a Viacomnál és a Junonál.


Az itt olvasható oldalak egyetlen személy véleményét tükrözik.
Minden itt megjelenő tartalom ©1999-2005 Joel Spolsky. Minden jog fenntartva.

FogBUGZ | CityDesk | Fog Creek Software | Joel Spolsky