Ugrás a tartalomhoz

Delegálás (objektumorientált programozás)

A Wikipédiából, a szabad enciklopédiából

Az objektumorientált programozásban a delegálás alatt az objektum (a fogadó) egy adattagjának (property vagy metódus) kiértékelését értjük egy másik objektum (a küldő) kontextusában. A delegálás lehet explicit vagy implicit. Az explicit delegálás átadja a küldő objektumot a fogadó objektumnak. Ez a művelet bármely objektumorientált nyelven elvégezhető. Az implicit delegáláshoz szükség van a szolgáltatás nyelvi támogatására és a nyelv tagkeresési szabályai szerint történik. Az implicit delegálás a viselkedés újra felhasználásának alapvető módszere a prototípus-alapú programozásban. Az osztályszíntű programozásban ennek megfelelője az öröklődés. A JavaScript és a Self a két legismertebb példája a nyelvi szintű delegálást támogató programozási nyelveknek. A Self programnyelv beépíti a delegáció fogalmát az önmagára történő hívások metódusfeloldására használt mutálható szülőhelyek fogalmán keresztül.

A delegálást különböző objektumok közötti kapcsolatok leírására is lehet használni. Fontos megemlíteni, hogy gyakran összetévesztik olyan fogalmakkal, amelyek más objektumok használatára épülnek, mint a konzultálás és az aggregálás. A továbbítás (forwarding) is egy jó példa erre. Itt egy tagérték kiértékelődik egy objektumban az által, hogy az adott adattagot kiértékeljük egy másik objektumban, a fogadó objektum kontextusában (amikor egy burkoló objektum nem adja tovább önmagát a burkolt objektumnak). A delegálási minta egy szoftvertervezési minta a delegáció implementálására, bár használják a kifejezést lazább kontextusban a konzultációra és a továbbításra is.

Áttekintés

[szerkesztés]

Lieberman 1986-os „Prototípusos objektumok használata a megosztott viselkedés megvalósításához objektumorientált rendszerekben” tanulmányában fogalmazta meg a delegációt ebben az értelemben, mint egy programnyelvi tulajdonságot, amely metóduskeresési szabályokat használ önmaga meghívására.

A dinamikus kötés a delegálás alapja. Ez lehetővé teszi, hogy futási időben különböző kódszegmenseket hívjon meg a metódus. Gyakran használják ezt a programozási technikát a macOS-ben (és elődjében, a NeXTStepben) a programkomponensek viselkedésének testreszabására. A delegálásnak köszönhetően egy, az operációs rendszer által biztosított osztály használata is elég az ablakok kezelésére, mivel szükség esetén az alapértelmezett viselkedés programspecifikus delegációval felülírható. Például, amikor a felhasználó az ablakbezáró gombra kattint, az ablakkezelő egy windowShouldClose: hívást küld a delegáltnak. Mentésre váró adatok esetén a delegált késleltetheti az ablak bezárását.

A delegálás meghatározható (és megkülönböztethető a továbbítástól), mint önmaga késői kötésének egy formája:

... a szülő self (vagy this) változójának küldött üzenetek "visszatérnek" az üzenetet eredetileg fogadó objektumhoz.

Tehát a definíció időpontjában a self fogadó objektum metódusdefinícióban nem statikusan kötődik az objektumhoz (például fordítási időben, vagy amikor a függvény egy objektumhoz tartozik). Kiértékelési időben kötődik az objektumhoz.

Sokan előnyben részesítik a delegálást az öröklődéssel szemben, arra hivatkozva, hogy olvashatóbbá és értelmezhetőbbé teszi a programkódot. Az explicit delegálás viszonylag közismert, azonban kevés felkapott programozási nyelvben található meg az öröklődés alternatív modelljeként. A delegáció és öröklődés közötti kapcsolat bonyolult; egyes szerzők egyenértékűnek tartják őket, vagy egyiket a másik különleges esetének.

Nyelvi támogatás a delegációhoz

[szerkesztés]

Ha egy nyelv támogatja a metóduskeresési szabályokon keresztüli delegálást, akkor a metódus továbbítás ugyanúgy működik, mint az öröklődő virtuális metódusoknál. Így mindig a legspecifikusabb metódus kerül kiválasztásra a metóduskeresés eredményeként. Ezért szerepel a metóduskeresés elején az eredeti fogadó entitás, akkor is, ha továbbadta a vezérlést egy másik objektumnak. (delegációs linken keresztül teszi, nem objektum hivatkozás segítségével)

A delegálás előnye, hogy képes futási időben az entitások egy adott részhalmazát befolyásolni, eltávolítani. Ez annak köszönhető, hogy futási időben valósul meg a delegációs hivatkozás. Ezzel szemben, az öröklődés a példányok helyett a típusra fókuszál és fordítási időben valósul meg. Továbbá, az öröklődés statikusan típusellenőrizhető, míg a delegálás általában generikusok segítsége nélkül erre nem képes (bár korlátozott változatai lehetnek statikusan típusbiztosak). A delegálást akár „konkrét objektumok futásidejű öröklődésének” is nevezhetjük.

C# / Java- szerű nyelvű pszeudokód:

class A {

void foo() {

  // a "this" más nyelvekben “current”, “me” illetve “self”-ként

     szerepelhet

  this.bar();

}

void bar() {

  print("a.bar");

}

};

class B {

private delegate A a; // delegációs hivatkozás


public B(A a) {

  this.a = a;

}

void foo() {

  a.foo(); // foo() hívása az a példányán

}

void bar() {

  print("b.bar");

}

};

a = new A();

b = new B(a); // delegálás kialakítása két objektum között

A b.foo() hívás eredményeként b.bar érték íródik a konzolra, mivel a this az eredeti fogadó objektumra b-re utal a kontextusában. Az ebből eredő this -beli kétértelműséget tárgyskizofréniának hívják.

Az implicit this explicit paraméterre fordításával (B-ben az a delegateje), az a.foo() hívás A.foo(b)-re változik. Itt az a típusát használjuk metódusfeloldáshoz és a b delegáló objektumra vonatkozik a this argumentum.

Öröklődéssel az analóg kód (nagybetűkkel hangsúlyozva, hogy a felbontás nem objektumokon hanem osztályokon alapul):

class A {
  void foo() {
    this.bar();
  }
  void bar() {
    print("A.bar");
  }
}; 
class B extends A {
  public B() {}
  void foo() {
    super.foo(); // meghívja (A) ősosztály foo() metódusát
  }
  void bar() {
    print("B.bar");
  }
};
b = new B();

A b.foo() hívás B.bar-t eredményez. Ebben az esetben this egyértelmű: csak egy objektum van, b, és a this.bar() az alosztályon lévő metódusra oldódik fel.

A programozási nyelvek nem szokták támogatni a delegálásnak ezt a szokatlan formáját nyelvi koncepcióként. Ez alól azonban létezik néhány kivétel.

Kettős öröklődés

[szerkesztés]

A kettős öröklődés akkor alkalmazható, ha az adott nyelv támogatja a delegációt és az öröklődést is. Ebben az esetben minkét mechanizmus végrehajtódik:

class C extends A {
  delegationlink D d;
}

Ez további metóduskeresési szabályokat igényel, mivel most potenciálisan két metódus létezhet és egyszerre lehetnek a legspecifikusabbak (a két keresési útvonal miatt).

Kapcsolódó területek

[szerkesztés]

A delegálás egy alacsony szintű mechanizmus. Célja az entitások közti kód és adat megosztása. Emiatt mondható, hogy más nyelvi konstrukciók alapját képezi. A szereporientált programozási nyelvek valóban használták a delegációt. Sok régi nyelv ezzel szemben az aggregációt használta, miközben azt állították, hogy delegációt használnak. Ez mégsem tekinthető csalásnak, ha a fent említett kettős öröklődés definícióját figyelembe vesszük.

Újabban a delegáció elosztásával is foglalkoznak. Például egy keresőmotor felhasználói (akik olcsó szállodaszobát keresnek) delegációval használhatnak egy megosztott entitást annak érdekében, hogy a legmegfelelőbb és általánosan újrahasznosítható funkcionalitásokat megosszák.

Ernst és Lorenz 2003-ban is javasolta a delegációt a tanácsadás feloldására az aspektusorientált programozásban.

Hivatkozások

[szerkesztés]
  • Lieberman, Henry. Using prototypical objects to implement shared behavior in object-oriented systems, Conference proceedings on Object-oriented programming systems, languages and applications, 214–223. o.. DOI: 10.1145/960112.28718 (1986) 
  • Lynn Andrea Stein, Henry Liberman, David Ungar: A shared view of sharing: The Treaty of Orlando. In: Won Kim, Frederick H. Lochovsky (Eds.): Object-Oriented Concepts, Databases, and Applications ACM Press, New York 1989, ch. 3, pp. 31–48 ISBN 0-201-14410-7 (online at Citeseer)
  • Gamma, Erich. Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley (1995). ISBN 978-0-201-63361-0 
  • Malenfant, J.: On the Semantic Diversity of Delegation-Based Programming Languages, Proceedings of the OOPSLA95, New York: ACM 1995, pp. 215–230.
  • Beck, Kent. Smalltalk Best Practice Patterns. Prentice Hall (1997). ISBN 978-0134769042 
  • Kasper Bilsted Graversen: The nature of roles---A taxonomic analysis of roles as a language construct. Ph.D. Thesis 2006, (Online at IT University of Copenhagen)

Fordítás

[szerkesztés]

Ez a szócikk részben vagy egészben a Delegation (object-oriented programming) című angol Wikipédia-szócikk ezen változatának 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.

További információk

[szerkesztés]

Kapcsolódó szócikkek

[szerkesztés]