Späte Bindung - Late binding


Late Binding , Dynamic Binding oder Dynamic Linkage – obwohl nicht identisch mit dem dynamischen Linken importierter Codebibliotheken – ist ein Computerprogrammiermechanismus, bei dem die Methode, die für ein Objekt aufgerufen wird, oder die Funktion, die mit Argumenten aufgerufen wird, nach Namen gesucht wird zur Laufzeit . Mit anderen Worten, ein Name wird zur Laufzeit und nicht während der Kompilierung mit einer bestimmten Operation oder einem bestimmten Objekt verknüpft.

Beim frühen Binden oder statischen Binden in einer objektorientierten Sprache fixiert die Kompilierungsphase alle Arten von Variablen und Ausdrücken. Diese wird im kompilierten Programm üblicherweise als Offset in einer virtuellen Methodentabelle ("v-table") gespeichert . Im Gegensatz dazu liest der Compiler bei der späten Bindung nicht genügend Informationen, um zu überprüfen, ob die Methode vorhanden ist, oder ihren Slot an die V-Tabelle zu binden. Stattdessen wird die Methode zur Laufzeit nach dem Namen gesucht.

Der primäre Vorteil der Verwendung der späte Bindung in Component Object Model (COM) Programmierung ist , dass es nicht die Compiler benötigt die Bibliotheken zu verweisen , die das Objekt zu enthalten Kompilierung . Dies macht den Kompilierungsprozess widerstandsfähiger gegenüber Versionskonflikten, bei denen die V-Tabelle der Klasse versehentlich geändert werden kann. (Dies ist bei Just-in-Time-Kompilierungs- kompilierten Plattformen wie .NET oder Java kein Problem, da die V-Tabelle zur Laufzeit von der virtuellen Maschine für die Bibliotheken erstellt wird, während sie in die laufende Anwendung geladen werden.)

Geschichte

Der Begriff "späte Bindung" stammt mindestens aus den 1960er Jahren, wo er in den Mitteilungen des ACM zu finden ist . Der Begriff wurde häufig verwendet, um Aufrufkonventionen in Sprachen wie Lisp zu beschreiben, wenn auch in der Regel mit negativen Konnotationen in Bezug auf die Leistung.

In den 1980er Jahren popularisierte Smalltalk die objektorientierte Programmierung (OOP) und damit die späte Bindung. Alan Kay sagte einmal: "OOP bedeutet für mich nur Nachrichtenübermittlung, lokale Aufbewahrung und Schutz und Verbergen von Zustandsprozessen und extrem spätes Binden aller Dinge. Dies kann in Smalltalk und in LISP erfolgen. Es gibt möglicherweise andere Systeme in die dies möglich ist, aber ich kenne sie nicht."

Anfang bis Mitte der 1990er Jahre hat Microsoft seinen COM-Standard als binäre Schnittstelle zwischen verschiedenen OOP-Programmiersprachen stark gefördert. Die COM-Programmierung förderte gleichermaßen frühes und spätes Binden, wobei viele Sprachen beides auf Syntaxebene unterstützen.

Im Jahr 2000 prägte Alex Martelli den Begriff „ Ententyping “, um auf ein ähnliches Konzept zu verweisen, jedoch mit einer anderen Betonung. Während sich die späte Bindung im Allgemeinen auf Implementierungsdetails konzentriert, konzentriert sich Duck-Typing auf die Fähigkeit, Typen zu ignorieren und sich auf die Methoden zu konzentrieren, die ein Objekt derzeit hat.

Verspätete verbindliche Implementierungen

Late Binding in dynamisch typisierten objektorientierten Sprachen

In den meisten dynamisch typisierten Sprachen kann die Liste der Methoden für ein Objekt zur Laufzeit geändert werden. Dies erfordert eine späte Bindung.

Späte Bindung in Lisp

In Lispel . spät gebundene globale Funktionsaufrufe werden zur Laufzeit effizient über die Funktionszelle eines Symbols nachgeschlagen . Diese Funktionsbindungen sind veränderbar.

Beispiel für eine interaktive Clozure Common Lisp- Sitzung:

? (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>

Late Binding in C++

In C++ bezieht sich die späte Bindung (auch "dynamische Bindung" genannt) auf das, was normalerweise passiert, wenn das virtualSchlüsselwort in der Deklaration einer Methode verwendet wird. C++ erstellt dann eine sogenannte virtuelle Tabelle, eine Nachschlagetabelle für solche Funktionen, die beim Aufruf immer zu Rate gezogen wird. Üblicherweise wird der Begriff „späte Bindung“ zugunsten des „ dynamischen Versands “ verwendet.

Late Binding in COM-Sprachen

Bei der COM-Programmierung wird ein spät gebundener Methodenaufruf über die IDispatch- Schnittstelle ausgeführt. Einige COM-basierte Sprachen wie Visual Basic 6 bieten syntaktische Unterstützung für den Aufruf dieser Schnittstelle. Dies geschieht, indem der Typ der Variablen als Object definiert wird. Andere wie C++ erfordern, dass Sie GetIDsOfNames explizit aufrufen, um eine Methode zu suchen, und Invoke, um sie aufzurufen.

Späte Bindung in .NET

In .NET bezieht sich Late Binding auf das Überschreiben einer virtualMethode wie C++ oder das Implementieren einer Schnittstelle. Der Compiler erstellt virtuelle Tabellen für jeden virtuellen oder Schnittstellenmethodenaufruf, der zur Laufzeit verwendet wird, um die auszuführende Implementierung zu bestimmen.

Ebenso wie COM und Java stellt die Common Language Runtime Reflexions-APIs bereit, die späte Bindungsaufrufe durchführen können. Die Verwendung dieser Anrufe variiert je nach Sprache.

Mit C# 4 fügte die Sprache auch den "dynamischen" Pseudotyp hinzu. Dies würde anstelle des Objekttyps verwendet werden, um anzuzeigen, dass eine späte Bindung erwünscht ist. Der benötigte spezifische späte Bindungsmechanismus wird zur Laufzeit unter Verwendung der Dynamic Language Runtime als Ausgangspunkt bestimmt.

Visual Basic verwendet sie immer dann, wenn die Variable vom Typ Object ist und die Compiler-Direktive "Option Strict Off" in Kraft ist. Dies ist die Standardeinstellung für ein neues VB-Projekt. Vor Version 9 konnten nur .NET- und COM-Objekte spät gebunden werden. Mit VB 10 wurde dies auf DLR-basierte Objekte erweitert.

Späte Bindung in Java

Es gibt drei Definitionen für die späte Bindung in Java.

In frühen Dokumenten zu Java wurde diskutiert, wie Klassen zur Kompilierzeit nicht miteinander verknüpft waren. Während Typen zur Kompilierzeit statisch überprüft werden, könnten verschiedene Implementierungen für Klassen kurz vor der Laufzeit einfach durch Überschreiben der Klassendatei ausgelagert werden. Solange die neue Klassendefinition dieselben Klassen- und Methodennamen hatte, funktionierte der Code noch. In diesem Sinne ähnelt es der traditionellen Definition der späten Bindung.

Derzeit ist es in der Java-Programmierung weit verbreitet, den Begriff Late Binding als Synonym für Dynamic Dispatch zu verwenden . Dies bezieht sich insbesondere auf den Single-Dispatch- Mechanismus von Java, der mit virtuellen Methoden verwendet wird.

Schließlich kann Java mit seinen Reflection-APIs und Typintrospektion Late Binding verwenden, ähnlich wie bei der COM- und .NET-Programmierung. Im Allgemeinen nennen diejenigen, die nur in Java programmieren, diese späte Bindung nicht. Ebenso ist die Verwendung von "Duck-Typing"-Techniken in der Java-Programmierung verpönt, stattdessen werden abstrakte Schnittstellen verwendet.

Oracle, der derzeitige Besitzer von Java, verwendet bekanntlich den Begriff Late Binding im Sinne von "Duck-Typing", wenn Java und andere Sprachen in derselben Dokumentation diskutiert werden.

Frühe vs. späte Bindung in PL/SQL und Ada

Bei Verwendung der frühen Bindung zwischen Ada und einer in der Datenbank gespeicherten Prozedur wird ein Zeitstempel überprüft, um sicherzustellen, dass sich die gespeicherte Prozedur seit der Kompilierung des Codes nicht geändert hat. Dies ermöglicht schnellere Ausführungen und verhindert, dass die Anwendung mit der falschen Version einer gespeicherten Prozedur ausgeführt wird.

Bei Verwendung von Late Binding wird die Zeitstempelprüfung nicht durchgeführt und die Stored Procedure wird über einen anonymen PL/SQL-Block ausgeführt. Dies kann zwar langsamer sein, erfordert jedoch keine Neukompilierung aller Clientanwendungen, wenn sich eine gespeicherte Prozedur ändert.

Diese Unterscheidung scheint nur für PL/SQL und Ada zu gelten. Andere Sprachen, die PL/SQL-Prozeduren aufrufen können, sowie andere Datenbank-Engines verwenden nur Late Binding.

Kritik

Die späte Bindung hat eine schlechtere Leistung als ein früh gebundener Methodenaufruf. Bei den meisten Implementierungen muss die korrekte Methodenadresse bei jedem Aufruf anhand des Namens nachgeschlagen werden, was eine relativ teure Wörterbuchsuche und möglicherweise eine überladene Auflösungslogik erfordert, jedoch auf modernen Computern im Allgemeinen vernachlässigbar ist.

Bei einigen Compilern kann die späte Bindung die Verwendung der statischen Typprüfung verhindern. Bei einem späten gebundenen Aufruf muss der Compiler davon ausgehen, dass die Methode existiert. Dies bedeutet, dass ein einfacher Rechtschreibfehler dazu führen kann, dass ein Laufzeitfehler ausgelöst wird. Die genaue Ausnahme variiert je nach Sprache, aber sie wird normalerweise so genannt wie "Methode nicht gefunden" oder "Methode fehlt". Moderne Compiler vermeiden dies, indem sie sicherstellen, dass jeder mögliche Aufruf während der Kompilierung eine Implementierung haben muss.

Eine späte Bindung kann Formen der statischen Analyse verhindern, die von einer integrierten Entwicklungsumgebung (IDE) benötigt werden. Beispielsweise funktioniert die Funktion "Gehe zur Definition" einer IDE möglicherweise nicht bei einem spät gebundenen Aufruf, wenn die IDE keine Möglichkeit hat, zu wissen, auf welche Klasse sich der Aufruf bezieht. Eine moderne IDE löst dies insbesondere für objektorientierte Sprachen leicht, da eine spät gebundene Methode immer ein Interface oder eine Basisklasse spezifiziert, zu der "go to definition" führt, und "find all reference" verwendet werden kann, um alle Implementierungen zu finden oder überschreibt.

Ein ähnliches Problem besteht darin, dass ein mögliches Fehlen von Typisierungsinformationen die Erstellung von Abhängigkeitsdiagrammen verhindern kann. Andere Programmiermethoden wie abstrakte Schnittstellen können jedoch zu den gleichen Problemen führen. Eine moderne IDE kann solche Abhängigkeitsgraphen genauso einfach erstellen, wie sie "alle Verweise finden" handhabt.

Siehe auch

Verweise