Delegálás (objektumorientált programozás)
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]- A Delegate megvalósításának új módja a C++ nyelven
- Gyors küldöttek C++ nyelven
- PerfectJPattern nyílt forráskódú projekt, A Delegates újrafelhasználható megvalósítását biztosítja Java nyelven