Egy kis OOP elmélet

2009.05.13. 12:59

Kaptam egy mérsékelten humoros spam-et, amiben közmondások (vagy szólások? ebben sosem voltam jó) vannak kódként megfogalmazva. Önmagában nem ér meg egy bejegyzést, de úgy gondoltam, hogy alkalmas arra, hogy felhívjam a figyelmet néhány tipikus OOP tervezési hibára. Még mielőtt lehülyézne valaki, szólok, hogy értem én, hogy ez vicc, csak lesz*rom.

A leírt elképzelések nagyon elméletiek. A gyakorlatban legtöbbször nem tudjuk alkalmazni a szép tervezésre vonatkozó szabályokat, emiatt ezek igazából csak filozófálgatásra jó meglátások. Nos, lássuk a levél tartalmát:

 

 
// Ki korán kel, aranyat lel

if (userLoggedIn.getWakeUpTime() < strToTime("06:00:00"))

  userLoggedIn.foundItems.add(GOLD);

 

// Egyszer volt Budán kutyavásár

const int NUM_DOG_EXPO_IN_BUDA = 1;

 

// Ki mint vet, úgy arat

aratas.setQuality(vetes.getQuality());

 

// Ajándék lónak ne nézd a fogát

if (horse.getOrigin() == SOUVENIR)

  horse.teeth.canLookAt = false;

 

// A hazug embert hamarabb utolérik mint a sánta kutyát

bool doesTruthExist()

{

  return liar.getCaptureTime() < crippleDog.getCaptureTime();

}

 

// Kerülgeti mint macska a forró kását

agent.sideStep(cat.getWalkType(new Kasa(HOT)));

 

// Aki másnak vermet ás, maga esik bele

stack.push(stack.madeBy());

 

// A napra lehet nézni, de rá nem

sun.canLookAt = true;

she.canLookAt = false;

 

// Madarat tolláról, embert barátjáról

bird.setType(bird.getFeather().getType());

human.setType(human.getFriend().getType());

 

// Éhes disznó makkal álmodik

if (pig.getType() == HUNGRY)

  pig.startDreamAbout(MAKK);

 

// Nem a győzelem, a részvétel a fontos

winning.setPriority(LOW);

attendance.getPriority(HIGH);

 

// A szomszéd fűje mindíg zöldebb

bool Grass::compareGreenness(const Grass& other) const

{

  return other.getOwner() == NEIGHBOUR;

}

 

// Lassan járj, tovább érsz

passedDistance += 42.0 / WalkSpeed;

 

// Okos enged, szamár szenved

if (human.getType() == SMART) 

  human.Release();

else if (human.getType() == DONKEY)

  human.Suffer();

 

 Első példának nézzük ezt:

// Ajándék lónak ne nézd a fogát

if (horse.getOrigin() == SOUVENIR)
  horse.teeth.canLookAt = false;

Ez tipikus példája a felelősségi körök összekutyulásának. A ló foga nem tudhatja, hogy rá lehet-e nézni vagy sem. Persze bizonyos helyzetekben helyes lehet az ilyen kódszervezés, de semmiképpen nem olyan fogalmakkal, mint ló, fog és ránézni. Ez a kódrészlet helyesen így festene:

if (horse.getOrigin() == SOUVENIR)
{
  actor.registerCanLookat(horse.teeth, false);
}

Az aktor tulajdonsága az, hogy ránézhet-e a lóra, és a ránézés is az ő metódusa lesz (mondjuk: actor.LookAt(horse);)

Következő példa:

// A hazug embert hamarabb utolérik mint a sánta kutyát

bool doesTruthExist()
{
  return liar.getCaptureTime() < crippleDog.getCaptureTime();
}

Ha eltekintünk a vicctől, ez teljesen értelmetlen. Igazából ez nem tervezési hiba, hanem rossz specifikáció. Az, hogy egy esemény mennyi ideig tart (capturetime) nem lehet egy osztály tulajdonsága, hanem inkább egy mérés eredménye, ami független az osztálytól. Ezt jóra átírni nem tudom, mert a specifikáció (a komment) egy állítás, és egy mért eredménnyel (kell lennie) nem lehet egy állítást ütköztetni (ilyen probléma amúgy később is előfordul a szomszéddal meg a fűjével kapcsolatban). A kód akkor lenne jó, ha a komment kérdés lenne, és akkor is így festene:

// A hazug embert hamarabb utolérik mint a sánta kutyát?

bool doesTruthExist()
{
  captureData liarCaptureData = actor.Capture(liar);
  captureData crippledogCaptureData = actor.Capture(crippledog);
  return liarCaptureData.CaptureTime < crippledogCaptureData.CaptureTime;
}

Persze a túlbonyolított vicc sose jó. Menjünk tovább. Itt ugyanaz a probléma, mint a ló esetében:

// A napra lehet nézni, de rá nem

sun.canLookAt = true;
she.canLookAt = false;

Sem a nap, sem a csaj nem tudhatja magáról, hogy egy másik entitás rá tud-e nézni. Persze más megfogalmazásban ez is jó lehet, de ezekkel a fogalmakkal semmiképpen sem.

És utoljára:

// Lassan járj, tovább érsz

passedDistance += 42.0 / WalkSpeed;

Ez azt jelenti, hogy csak 42-t mehetünk. De miért pont 42? Mert az a válasz univerzum, meg a világmindenség legnagyobb kérdésére? Vagy maratont járunk? Nekem így jobban néz ki:

passedDistance += (1 / WalkSpeed) * time;

Persze ez csak vicc. Ja. Muhaha.




A bejegyzés trackback címe:

https://zsir.blog.hu/api/trackback/id/tr521118945

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

Nincsenek hozzászólások.

 

 

 

süti beállítások módosítása