A számítógép-programozásban a kétesélyes függvény egy programtervezési minta, amit keresztplatformos és skálázható fejlesztésben használnak.

Tekintsünk egy grafikus API-t a DrawPoint, DrawLine, és DrawSquare függvényekkel. Könnyen látható, hogy a DrawLine definiálható a DrawPoint és a DrawSquare a DrawLine segítségével. Ha ezt portolni kell egy újabb platformra, akkor ezeket vagy egyenként írjuk újra, ha van hozzá natív támogatás; vagy csak a DrawLine függvényt írja újra, a többit pedig a fentiek szerint keresztplatformos kódban valósítjuk meg. Erre a megközelítésre példa az X11 grafikus rendszer, amihez elég csak néhány primitívet megvalósítani, mert a többiek ezekre vannak visszavezetve egy magasabb rétegben.[1][2]

A kétesélyes függvény optimális, ha ilyen implementációt kell létrehozni. Mivel az első verziót gyorsan kell piacra dobni, azért az első megközelítés szerint visszavezetjük a függvényeket, és csak a primitíveket írjuk újra, míg a későbbi verziókra több idő jut, így megírható minden függvény önmagában. Az első port az első működő megvalósítás. Az alapvető API magába foglalja az önmagát támogató megvalósítást, és az összes többi ezt egészíti ki.

Egy példa C++-ban:

 class CBaseGfxAPI {
     virtual void DrawPoint(int x, int y) = 0; /* Abstract concept for the null driver */
     virtual void DrawLine(int x1, int y1, int x2, int y2) { /* DrawPoint() repeated */}
     virtual void DrawSquare(int x1, int y1, int x2, int y2) { /* DrawLine() repeated */}
 };

 class COriginalGfxAPI : public CBaseGfxAPI {
     virtual void DrawPoint(int x, int y) { /* The only necessary native calls */ }
     virtual void DrawLine(int x1, int y1, int x2, int y2) { /* If this function exists a native DrawLine
                                                                routine will be used. Otherwise the base
                                                                implementation is run. */}
 };

 class CNewGfxAPI : public CBaseGfxAPI {
     virtual void DrawPoint(int x, int y) { /* The only necessary for native calls */ }
 };

Jegyezzük meg, hogy a CBaseGfxAPI::DrawPoint függvényt sosem használják önmagában, mivel minden grafikus hívás valamelyik leszármazott osztályon keresztül megy. Így a CNewGfxAPI::DrawSquare első esélye az, hogy a CNewGfxAPI négyzetet renderel. Ha nincs natív implementáció, akkor az alaposztály hívódik meg, ahol a virtualizáció specializálja a függvényt, és a CNewGfxAPI::DrawLine hívódik meg. Ez egy második esélyt ad a CNewGfxAPI osztálynak arra, hogy natív kódot használjon, ha valahogy elérhető.

Ezen a módon elméletben egy 3D motor is felépíthető szoftver raszterizációval úgy, hogy csak a DrawPoint natív függvényt használja más függvények közbeiktatásával. A gyakorlatban azonban ez reménytelenül lassú, csak annyi a jelentősége, hogy bemutassa a kétesélyes függvények lehetőségeit.

Jegyzetek szerkesztés

  1. Susan Angebranndt, Raymond Drewry, Philip Karlton, Todd Newman, "Definition of the Porting Layer for the X v11 Sample Server", MIT, 1988.
  2. Susan Angebranndt, Raymond Drewry, Philip Karlton, Todd Newman, "Strategies for Porting the X v11 Sample Server", Mit 1988.

Források szerkesztés

  • Goodwin, Steven. Cross-Platform Game Programming. Charles River Media (2005). ISBN 1-58450-379-3 

Fordítás szerkesztés

Ez a szócikk részben vagy egészben a Double-chance function című angol Wikipédia-szócikk fordításán alapul. Az eredeti cikk szerkesztőit annak laptörténete sorolja fel. Ez a jelzés csupán a megfogalmazás eredetét és a szerzői jogokat jelzi, nem szolgál a cikkben szereplő információk forrásmegjelöléseként.