A számítástechnikában a késői kötés vagy dinamikus csatolás[1] – bár nem azonos folyamat az importált kódkönyvtárak dinamikus összekapcsolásával – olyan számítógépes programozási mechanizmus, amelyben egy objektumra hívódik meg metódus vagy az argumentumokkal hívódik meg függvény, futásidőben. Más szavakkal, egy név egy adott művelethez vagy objektumhoz van társítva futási időben, nem pedig fordítás közben. A dinamikus kötés elnevezést csak ritkán használják,[2] de gyakrabban alkalmazzák a dinamikus hatókörre utalva.

A korai kötésnél vagy statikus kötésnél egy objektumorientált nyelvben a fordítási fázis minden típusú változót és kifejezést rögzít. Ezt általában a lefordított programban eltolásként tárolják egy virtuális metódustáblában ("v-tábla").[3] Ezzel szemben a késői kötésnél a fordító nem olvas elég információt ahhoz, hogy megerősítse a metódus létezését, vagy ahhoz, hogy köti-e a slotját a v-táblázaton. Ehelyett a metódus név szerint keres futás közben.

A COM (Component Object Model) programozásban a késői kötés használatának elsődleges előnye az, hogy nem szükséges, hogy a fordító hivatkozzon azokra a könyvtárakra, amelyek a fordítás során tartalmazzák az objektumot. Így a fordítási folyamat ellenállóbbá válik a verziókonfliktusokkal szemben, amelyekben az osztály v-táblázata véletlenül módosulhat. (Ez nem ad aggodalomra okot a just-in-time fordítással összeállított platformokon, mint pl. NET vagy Java, mert a v-táblát futás közben hozza létre a virtuális gép a futó alkalmazásba való betöltésekor a könyvtárakkal szemben.[4]

Történet szerkesztés

A "késői kötés" elnevezés legalább az 1960-as évekre nyúlik vissza, ahol megtalálható a Communications of the ACM-ben. Az elnevezést széles körben használták a hívási konvenciók leírása során olyan nyelveken, mint a Lisp, bár általában negatív konnotációval a teljesítményre vonatkozólag.[5]

Az 1980-as években a Smalltalk népszerűsítette az objektumorientált programozást (OOP), és ezzel együtt a késői kötést is. Alan Kay egyszer azt mondta: "Az OOP számomra csak az üzenetküldést, a helyi megőrzést, az állapotfolyamatok védelmét és elrejtését jelenti, és minden dolog rendkívül késői kötését. Megtehető Smalltalkban és LISP-ben. Lehetséges az, hogy vannak egyéb rendszerek, amelyekben ez lehetséges, de ennek nem vagyok tudatában."[6]

Az 1990-es évek elején és közepén a Microsoft erőteljesen népszerűsítette a COM-szabványát mint a különböző OOP programozási nyelvek közötti bináris interfész. A COM programozás egyaránt elősegítette a korai és késői kötést, számos nyelv támogatja mindkettőt szintaktikai szinten.

2000-ben Alex Martelli megalkotta a " kacsa gépelés " kifejezést, hogy hasonló fogalomra utaljon, de más hangsúlyozással. Míg a késői kötés általában a megvalósítás részleteire összpontosít, addig a kacsa gépelés arra a képességre, hogy figyelmen kívül hagyja a típusokat, és az objektum aktuális metódusaira koncentráljon.

Késői kötési implementációk szerkesztés

Késői kötés a dinamikusan tipizált objektumorientált nyelvekben szerkesztés

A legtöbb dinamikusan tipizált nyelvben az objektumon lévő eljárások listája futás közben változtatható. Ehhez késői kötés szükséges.

Késői kötés Lispben szerkesztés

A Lisp programban a késői kötött globális függvényhívások hatékonyan megkereshetők futási időben egy szimbólum függvénycellán keresztül. Ezek a függvénykötések változtathatók.

Példa egy interaktív Clozure Common Lisp munkamenet használatára:

? (defun foo ()
  (bar pi))  ; a still undefined function BAR gets called
;Compiler warnings :
;  In FOO: Undefined function BAR
FOO

? (defun bar (x)  ; now we define it
  (* x 2))
BAR

? (foo)  ; calling foo and it uses the recent definition of BAR
6.283185307179586D0

? (defun bar (x)  ; now we redefine BAR
  (* x 1000))
BAR

? (foo)  ; FOO now calls the new function, there is no need to recompile/link/load FOO
3141.592653589793D0

? (type-of 'bar)  ; BAR is a symbol
SYMBOL

? (symbol-function 'bar) ; the symbol BAR has a function binding
#<Compiled-function BAR #x302000D1B21F>

Késői kötés C++ nyelven szerkesztés

A C++ nyelvben a késői kötés (más néven "dinamikus kötés") arra utal, hogy általában mi történik, amikor a virtual kulcsszót használják egy metódus deklarációjában. A C++ ezután létrehoz egy úgynevezett virtuális táblát, amely az ilyen függvények keresési táblája, ami mindig lekérdezésre kerül, amikor meghívják őket.[7] Általában a "késői kötés" kifejezést a "dinamikus feladás" javára használják.

Késői kötés a COM nyelveken szerkesztés

A COM programozásban az IDispatch interfészen keresztül egy késői kötött metódushívás történik. Egyes COM-alapú nyelvek, mint például a Visual Basic 6 szintaktikai támogatással rendelkeznek ennek a felületnek a hívásához.[8] Ez úgy lehetséges, hogy a változó típusát Object-ként határozzuk meg. Másokhoz, például a C++-hoz, kifejezetten meg kell hívnia a GetIDsOfNames-t a metódus kereséséhez, az Invoke-ot pedig a meghíváshoz.

Késői kötés a .NET-ben szerkesztés

A .NET-ben, a késői kötés egy virtual eljárás, például a C++ felülbírálására vagy egy interfész megvalósítására utal. A fordító minden virtuális vagy interfész metódushíváshoz virtuális táblákat készít, amelyeket futási időben használnak a végrehajtandó megvalósítás meghatározására.

A COM-hoz és a Java-hoz hasonlóan a Common Language Runtime is biztosít olyan tükrözési API-kat, amelyek késleltetett kötési hívásokat indíthatnak el. E hívások használata nyelvenként különböző lehet.

A C#4-nél a nyelv hozzáadta a "dinamikus" pszeudo-típust is. Ez az Object típus helyett használható annak jelzésére, hogy késői kötés kívánatos. A szükséges konkrét késői kötési mechanizmust futási időben határozzák meg a Dynamic Language Runtime kiindulási pontként használva.

A Visual Basic akkor alkalmazza ezeket, amikor a változó Object típusú, és az "Option Strict Off" fordítói direktíva érvényben van. Ez az alapértelmezett beállítás egy új VB-projekthez. A 9-es verzió előtt csak a .NET és COM objektumok későn köthetők. A VB 10-nél ezt kiterjesztették a DLR-alapú objektumokra is.

Késői kötés Java nyelven szerkesztés

A Java-ban három definíció létezik a késői kötésre.

A Java korai dokumentumai azt vitatták, hogy az osztályokat hogyan nem kapcsolták össze a fordításkor. Míg a típusokat statikusan ellenőrzik a fordításkor, az osztályok különböző implementációit közvetlenül a futásidő előtt ki lehet cserélni az osztályfájl felülírásával. Amíg az új osztálydefiníció ugyanazokkal az osztály- és metódusnevekkel bír, a kód továbbra is működni fog. Ebben az értelemben hasonló a késői kötés hagyományos meghatározásához.

Jelenleg a Java programozásban népszerű a késői kötés kifejezés a dinamikus küldés szinonimájaként. Ez konkrétan a Java virtuális metódusokkal használt egyetlen küldési mechanizmusára vonatkozik.

Végül a Java használhat késői kötést a tükrözési API-k segítségével, és ugyanúgy begépelheti az introspekciót, mint ahogyan a COM-ban és a .NET programozásban is. Általában azok, akik csak Java nyelven programoznak, nem hívják ezt a késői kötést. Hasonlóképpen, a "kacsa gépelés" technikák használata rosszindulatú a Java programozásban, helyette absztrakt felületeket használnak.

Az Oracle, a Java jelenlegi tulajdonosa köztudottan a "kacsa gépelés" értelmében használja a késői kötés kifejezést, amikor a Java-ról és más nyelvekről beszél ugyanabban a dokumentációban.[9]

Korai vs. késői kötés PL/SQL-ben és Ada-ban szerkesztés

Ha korai összerendelést használ az Ada és egy adatbázisban tárolt eljárás között, egy időbélyeg ellenőrzi, hogy a tárolt eljárás nem változott-e a kód lefordítása óta. Ez gyorsabb végrehajtást tesz lehetővé, és meggátolja, hogy az alkalmazás a tárolt eljárás rossz verziójával szemben fusson.[10]

Késői kötés használatakor az időbélyeg-ellenőrzés nem történik meg, a tárolt eljárás pedig egy névtelen PL/SQL blokkon keresztül fut le. Bár ez lassabb is lehet, szükségtelenné válik az összes ügyfélalkalmazás újrafordítása, amikor egy tárolt eljárás megváltozik.

Úgy tűnik, hogy ez a megkülönböztetés egyedülálló a PL/SQL és az Ada esetében. Más nyelvek, amelyek PL/SQL-eljárásokat hívhatnak, valamint más adatbázismotorok csak késői összerendelést használnak.

Kritika szerkesztés

A késői kötés gyengébb teljesítményt nyújt, mint a korai kötésű metódushívás. A legtöbb megvalósításban a helyes metóduscímet minden hívásnál név szerint kell kikeresni, ami viszonylag költséges szótárkeresést és esetleges túlterhelés-feloldási logikát igényel. A legtöbb alkalmazásban a többlet számítási és időigény már elhanyagolható a modern számítógépeken.

Egyes fordítóknál a késői kötés megakadályozhatja a statikus típusellenőrzés alkalmazását. Késői kötött hívás indításakor a fordítónak feltételeznie kell azt, hogy a metódus létezik. Ez azt jelenti, hogy egy egyszerű helyesírási hiba futásidejű hibát okozhat. A modern fordítók ezt elkerülik azzal, hogy a fordítás során minden lehetséges hívásnak rendelkeznie kell implementációval.

A késői kötés megakadályozhatja az integrált fejlesztői környezet (IDE) által igényelt statikus elemzés formáit. Előfordulhat például, hogy egy IDE „meghatározásra lépés” funkciója nem működik későn kötött hívás esetén, ha az IDE nem tudja megtudni, hogy a hívás melyik osztályra vonatkozhat. Egy modern IDE különösen az objektum-orientált nyelvek esetében könnyen megoldja ezt, mivel a késői kötésű metódusok mindig megadnak egy interfészt vagy egy alaposztályt, ahová a "meghatározásra lépés" vezet, a "minden hivatkozás keresése" pedig az összes megkeresésére megkeresésére vagy felülírására használható.[11]

Jegyzetek szerkesztés

  1. Schreiner, Axel-Tobias. Object-Oriented Programming With ANSI-C. Munich: Hanser, 15. o. (1994). ISBN 3-446-17426-5 
  2. Booch, Grady. Object-oriented Analysis and Design. Addison-Wesley, 1994. p71
  3. Using early binding and late binding in Automation. Microsoft, 2003. szeptember 6. [2014. június 27-i dátummal az eredetiből archiválva]. (Hozzáférés: 2014. június 27.)
  4. The Structure of the Java Virtual Machine: Dynamic Linking. Sun Microsystems, 1999. (Hozzáférés: 2013. szeptember 21.)
  5. Software engineering techniques, J. N. Buxton, Brian Randell, NATO Science Committee, NATO Science Committee, 1970
  6. Dr. Alan Kay on the Meaning of "Object-Oriented Programming". Purl.org. [2020. szeptember 16-i dátummal az eredetiből archiválva]. (Hozzáférés: 2013. augusztus 16.)
  7. 12.5 — The virtual table « Learn C. Learncpp.com, 2008. február 8. (Hozzáférés: 2013. augusztus 16.)
  8. Using early binding and late binding in Automation. Support.microsoft.com. (Hozzáférés: 2011. január 15.)
  9. Calling into WebLogic Server from a COM Client Application. Download.oracle.com. (Hozzáférés: 2013. augusztus 16.)
  10. Early and Late Binding, Oracle SQL *Module for Ada Programmer's Guide. Download.oracle.com. (Hozzáférés: 2011. január 15.)
  11. KathleenDollard: Early and Late Binding - Visual Basic (amerikai angol nyelven). learn.microsoft.com. (Hozzáférés: 2023. április 12.)

Fordítás szerkesztés

Ez a szócikk részben vagy egészben a Late binding 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.

Kapcsolódó szócikkek szerkesztés