tifyty

pure Java, what else ?

Mit gondolhatott a költő

Volt már olyan, hogy csúnya kódot kellett refaktorálnom. Ez mindenkivel előfordul az élete során, talán csak a nepáli kecskepásztorok a kivételek, főleg ha birkák. Eleddig azonban ezek a csúnyaságok javarészt tapasztalatlanságból adódtak. Igen, akár az én tapasztalatlanságomból is: elő nem venném a kódot amit 2005-ben gyártottam. Mostanában azonban olyan kódokat látok, amelyiket nem gyárthatott kezdő junior. Meg van a súlya a kódnak, benne van a programozó egyénisége, gondolkodásmódja. Szinte már költészet.

Vannak egyszerűbbek:

String attrib = businessObject.getBusinessAttribute();
if( attrib == null || attrib.length() <= 0 ){
 ...

Már az is egy általánosan felteendő kérdés, hogy miért stringek az üzleti objektumok. Ez azonban általánosan elterjedt kódolási szokás, még abból a korból ered, amikor Perl-ben programoztunk (vagy nem). Végül is egy cím, egy irányítószám, egy bankszámlaszám, egy rendelési azonosító, egy láda térbeli mérete (pl. “22cm x 18cm x 11cm”) mind stringek (vagy nem). De mikor, és hogyan lehet egy string hossza negatív? A nulla hosszal nincs, gond, az is tiszta, hogy lehet a visszaadott érték null. De negatív hosszúságú string? CharSequence még csak csak lehetséges, na de string?

Mire gondolhatott a költő, amikor ezt írta? Mindig ezt a kérdést tették fel irodalom órán, és akkor sem értettem. Mondjuk arra, hogy éppen csikart a hasa, vagy kellett a honorárium a lakbér kifizetéséhez. Nem mindegy? Sokkal fontosabb, hogy milyen gondolatokat ébreszt a vers olvasása bennem. Szép ez a vers? Mert programkódnak csak limitáltan nevezhető, annál több benne a művészi érték. Mit gondoljak a tisztelt kollégáról, aki fentieket írta?

Valószínűleg megfontolt, és óvatos ember. Nem azt nézi, hogy egy string nulla hosszú-e, inkább arra kíváncsi, hogy pozitív számú karakter van-e benne. Biztos, ami biztos. Hátha egyszer szembe jön egy string aminek negatív a hossza. Az, hogy eddig még senki nem látott ilyet, nem bizonyítja, hogy valóban nincs is! Pont mint a jeti. (Már megint Nepál! Lehet ott valami!)

De a fenti kis kód maximum haiku-nak nevezhető. A következő viszont egy igazi szonett, amelyik felkészül a párhuzamosan futó szálra. Van olyan? Nem több szál, hanem egy. Egy szál, ami párhuzamosan fut. Még senki nem látott olyat? Az nem bizonyít semmit!

final ThreadLocal<MyType> lock = new ThreadLocal<MyType>();
	
  public void method() {
    if (lock.get() == null) {
      lock.set(this);
      try {
        init();
      } finally {
        lock.set(null);				
      }
    }
  }

Mit zárol ez a lock? Az adott szálat. Ha tehát az adott szál akarja még egyszer párhuzamosan futtatni a method() metódust, akkor az nem fog menni. Persze ki tudja mi van az init()-ben? Lehet, hogy rekurzívan vissza hív sok rétegen keresztül, és így varrja el a program a végtelen rekurziót. De nem, ezt megnéztük. Ilyet nem tesz. Annak egyébként lehetne értelme, hogy a szálhelyi (threadlocal) változó nem statikus. A rekurzív hívás (már ha lenne) ha másik objektumon hívná meg method() metódust, akkor ott egy másik szálhelyi változó állna strázsát az init() hívás előtt, és így beengedhetné. Tehát lehetne értelme a nem statikus szálhelyi változónak, ha éppen nem lenne az egész teljesen értelmetlen. Vagy én vagyok nepáli helikopter.

Hogy lehet ezt kezelni? Talán sztoikus nyugalommal, amit mi sem fejez ki jobban, mint egy haiku:

Ők programoznak,
Révedünk magunk elé.
Gyűlik sok maszat.

14 responses to “Mit gondolhatott a költő

  1. Kofa december 26, 2014 12:10 de.

    A ‘this’ egy szál? A lock pedig privát? Mert ha nem, kívülről módosítható (persze innentől az egész lock logika értelmetlen).
    A negatív hosszú Stringről jutott eszembe:
    http://wouter.coekaerts.be/2012/java-puzzle-cookies

  2. sarkiroka december 26, 2014 1:11 du.

    sokkal egyszerűbb furmányok is előfordulnak:

    if(false){…}

    utánajárás után a magyarázat: “egyszerűbb volt így, mint kikommentezni, aztán bennefelejtettem”
    és az idekapcsolódó idézetem:
    “Egyértelmű, hogy az elágazás mindig olyan vagylagos dolog, most vagy ide megy, vagy oda, maga sem tudja mit akar, szóval egyértelműen az ördög műve. Igaz Magyar Programozónak a kódja mindig lefut az első bittől az utolsóig, és nincs semmiféle mismásolás!”
    ( http://prog.hu/tarsalgo/?fid=173097&op=history&no=8 )

  3. tamasrev december 26, 2014 3:12 du.

    Az a legnagyobb élmény, hogy miután kizártál pár beteg use-case-t, kitakarítottad a kódot, akkor (2 héttel később) jön a hibajegy, hogy elromlott valami. És visszavezeted ide, és fogod a fejed, hogy ááá, azért kellett a lock, mert…

  4. szjanihu december 27, 2014 1:14 de.

    11 éve van nekünk DDD-nk és még mindig az anemic domain modell a “menő” a String business objektumokkal együtt. Nem tudom valaha eljut-e az iparág nagyobbik része oda, hogy felfogja, nem feltétlenül csak a technology stack az, amire oda kell figyelni.

  5. tudatlanka december 27, 2014 7:17 du.

    Mondd, kedves Péter! Az a második kód, amiben van egy lock.get és egy lock.set egymás után, az valóban így nézett ki az eredetiben? Ugyan vagy húsz éve leszoktam a programozásról, de ez a kódrészlet számomra eléggé hajmeresztő ebben a formában. Persze lehet, hogy csak a javat nem ismerem eléggé és ezért tűnik hibásnak. Feltéve, hogy jól értelmezem azt a kis kódot:
    1. Ellenőrzöm, hogy a lock be van-e állítva
    2. Ha nincs, akkor beállítom.
    Nem történhet olyan, hogy több szál egyszerre nyúl hozzá, véletlenül egyszerre kérdezik le a lock létét, egyszerre kapnak nemleges választ és elégedetten állítják be a lockot, mintha saját lenne?
    (inkább csak hangosan gondolkodom, mivel nagyon rég nem foglalkoztam ilyesmivel 😦 )

    Negatív string hossz: anno valamelyik tanárom javasolta, hogy ahol nem muszáj, ott ne egyenlőséget vizsgáljunk, mert… (persze hülyeség, mert így csak odébb tolom az esetleges hibát)

    • Peter Verhas december 27, 2014 7:30 du.

      Igen, ez valóban így nézett ki eredetiben. Ennek ellenére NEM történhet meg, hogy több szál nyúl hozzá egyszerre, mert ThreadLocal azaz minden egyes szál másik objektumot ad vissza a get-re illetve állít be a set-re. Tehát nem csak a pattern rossz, de még a megvalósítás is totál nonsense.

      • tudatlanka december 28, 2014 1:27 du.

        No igen, itt már látszik a finoman szólva hiányos java műveltségem 🙂
        Viszont így, hogy megnéztem a doksit, már nem látom annyira egyértelműen hibásnak a kódot, max. ha Bob bácsi Clean Code-ját veszem alapul, akkor talán a lock nevet cserélném másra. 🙂
        (na jó, nem akarok “szakérteni”, csak elsőre a “lock” elnevezés miatt elég nagy marhaságnak tűnt ez a kódrészlet. A java dokumentáció alapján már nem merem minősíteni, akár még működőképes is lehet, csak nem lockolást végez, ahogy elsőre gondoltam volna)

    • Peter Verhas december 27, 2014 7:37 du.

      “ahol nem muszáj, ott ne egyenlőséget vizsgáljunk”

      Ez maximum lebegőpontos számolásnál. Azt is el tudom képzelni, hogy int műveletnél régen, gépi kódban különböző összehasonlítások több/kevesebb órajel alatt futottak le. Ma már nem releváns.

      1. Olvashatóság, priority numero uno. Ezért van String-re is újabban isEmpty().
      2. Fail fast minden kódra. Éles kódban is. Ha ugyanis nem hal el, akkor onnan kezdve a mindenható kezében vagyunk. Egy rossz kód nagyon nagy károkat tud okozni. Aztán bizonyítsd be, hogy akaratlan programhiba miatt utalt át a programod milliókat a terroristáknak, robbantotta fel az atomerőművet, vagy állította le a plébános pace-maker-ét.

      • tudatlanka december 28, 2014 1:30 du.

        Nem, ez még valami olyan téma volt, hogy ne az egyezést vizsgáljuk, mert mi van, ha véletlenül alacsonyabb érték kerül az adott változóba, inkább nézzük a kisebb-egyenlőt, abból nem lehet baj.
        Na ez addig szép volt, míg az iskola egyetlen R20-as gépén (nekem úgy rémlik, ezt még a Hámánban mondták) 3-400 gyerek programkezdeményeit kellett futtatni és a végtelen ciklus végének eléréséhez nem állt rendelkezésre megfelelő erőforrás… 🙂

    • sarkiroka február 18, 2015 4:23 du.

      Valójában így kellene:
      if(xy.length() MAXLENGTH_OF_CLASSNAME)…
      merthát mi van ha tulcsordult negatív irányban és épp a pozitív maxintet kerülgeti 😀

      • sarkiroka február 18, 2015 4:26 du.

        Megette az belét a blog. Ez amolyan vezérlési szerkezet pacal. Szóval még egyszer :
        Valójában így kellene:

        if(xy.length() <= 0 || xy.length() > MAXLENGTH_OF_CLASSNAME)... 
        

        mert hát mi van ha túlcsordult negatív irányban és épp a pozitív maxintet kerülgeti 😀

Vélemény, hozzászólás?

Adatok megadása vagy bejelentkezés valamelyik ikonnal:

WordPress.com Logo

Hozzászólhat a WordPress.com felhasználói fiók használatával. Kilépés / Módosítás )

Twitter kép

Hozzászólhat a Twitter felhasználói fiók használatával. Kilépés / Módosítás )

Facebook kép

Hozzászólhat a Facebook felhasználói fiók használatával. Kilépés / Módosítás )

Google+ kép

Hozzászólhat a Google+ felhasználói fiók használatával. Kilépés / Módosítás )

Kapcsolódás: %s

%d blogger ezt kedveli: