Reliure tardive - Late binding


La liaison tardive , la liaison dynamique ou la liaison dynamique - bien qu'il ne s'agisse pas d'un processus identique à la liaison dynamique des bibliothèques de code importées - est un mécanisme de programmation informatique dans lequel la méthode appelée sur un objet, ou la fonction appelée avec des arguments, est recherchée par son nom à l' exécution . En d'autres termes, un nom est associé à une opération ou à un objet particulier lors de l'exécution, plutôt que lors de la compilation.

Avec la liaison anticipée , ou liaison statique , dans un langage orienté objet , la phase de compilation corrige tous les types de variables et d'expressions. Ceci est généralement stocké dans le programme compilé en tant qu'offset dans une table de méthode virtuelle ("v-table"). En revanche, avec la liaison tardive, le compilateur ne lit pas suffisamment d'informations pour vérifier l'existence de la méthode ou lier son emplacement sur la v-table. Au lieu de cela, la méthode est recherchée par son nom au moment de l'exécution.

Le principal avantage de l'utilisation de la liaison tardive dans la programmation COM ( Component Object Model ) est qu'elle n'exige pas que le compilateur référence les bibliothèques qui contiennent l'objet au moment de la compilation . Cela rend le processus de compilation plus résistant aux conflits de version, dans lesquels la table v de la classe peut être accidentellement modifiée. (Ce n'est pas un problème dans les plates-formes compilées juste à temps telles que .NET ou Java, car la v-table est créée au moment de l'exécution par la machine virtuelle par rapport aux bibliothèques lors de leur chargement dans l'application en cours d'exécution.)

Histoire

Le terme « liaison tardive » remonte au moins aux années 1960, où on le retrouve dans les Communications de l' ACM . Le terme était largement utilisé pour décrire les conventions d'appel dans des langages comme Lisp, bien qu'il ait généralement des connotations négatives sur les performances.

Dans les années 1980, Smalltalk a popularisé la programmation orientée objet (POO) et avec elle la liaison tardive. Alan Kay a dit un jour : « La POO pour moi ne signifie que la messagerie, la rétention locale, la protection et la dissimulation du processus d'état, et une liaison extrêmement tardive de toutes choses. Cela peut être fait en Smalltalk et en LISP. Il existe peut-être d'autres systèmes dans que c'est possible, mais je ne les connais pas."

Du début au milieu des années 90, Microsoft a fortement promu sa norme COM en tant qu'interface binaire entre différents langages de programmation POO. La programmation COM encourageait également la liaison précoce et tardive, de nombreux langages prenant en charge les deux au niveau de la syntaxe.

En 2000, Alex Martelli a inventé le terme « dactylographie du canard » pour désigner un concept similaire, mais avec un accent différent. Alors que la liaison tardive se concentre généralement sur les détails de l'implémentation, le typage duck se concentre sur la capacité d'ignorer les types et de se concentrer sur les méthodes dont dispose actuellement un objet.

Implémentations de liaison tardives

Liaison tardive dans les langages orientés objet à typage dynamique

Dans la plupart des langages à typage dynamique , la liste des méthodes sur un objet peut être modifiée au moment de l'exécution. Cela nécessite une reliure tardive.

Reliure tardive en Lisp

Dans Lisp . Les appels de fonction globale liés tardivement sont efficacement recherchés au moment de l'exécution via la cellule de fonction d' un symbole . Ces liaisons de fonction sont modifiables.

Exemple d'utilisation d'une session Clozure Common Lisp interactive :

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

Liaison tardive en C++

En C++, la liaison tardive (également appelée "liaison dynamique") fait référence à ce qui se passe normalement lorsque le virtualmot-clé est utilisé dans la déclaration d'une méthode. C++ crée ensuite une table dite virtuelle, qui est une table de recherche pour ces fonctions qui sera toujours consultée lorsqu'elles sont appelées. Habituellement, le terme « liaison tardive » est utilisé en faveur de « distribution dynamique ».

Reliure tardive dans les langages COM

Dans la programmation COM, un appel de méthode à liaison tardive est effectué à l'aide de l' interface IDispatch . Certains langages COM tels que Visual Basic 6 prennent en charge la syntaxe pour appeler cette interface. Cela se fait en définissant le type de la variable comme Objet. D'autres, tels que C++, nécessitent que vous appeliez explicitement GetIDsOfNames pour rechercher une méthode et Invoke pour l'appeler.

Liaison tardive dans .NET

Dans .NET, la liaison tardive fait référence au remplacement d' une virtualméthode telle que C++ ou à l'implémentation d'une interface. Le compilateur crée des tables virtuelles pour chaque appel de méthode virtuelle ou d'interface qui est utilisé au moment de l'exécution pour déterminer l'implémentation à exécuter.

Tout comme COM et Java, le Common Language Runtime fournit des API de réflexion qui peuvent effectuer des appels de liaison tardifs. L'utilisation de ces appels varie selon la langue.

Avec C# 4, le langage a également ajouté le pseudo-type "dynamique". Il serait utilisé à la place du type d'objet pour indiquer qu'une liaison tardive est souhaitée. Le mécanisme de liaison tardive spécifique requis est déterminé au moment de l'exécution en utilisant Dynamic Language Runtime comme point de départ.

Visual Basic les utilise chaque fois que la variable est de type Object et que la directive du compilateur "Option Strict Off" est en vigueur. Il s'agit du paramètre par défaut pour un nouveau projet VB. Avant la version 9, seuls les objets .NET et COM pouvaient être liés tardivement. Avec VB 10, cela a été étendu aux objets basés sur le DLR.

Liaison tardive en Java

Il existe trois définitions de la liaison tardive en Java.

Les premiers documents sur Java discutaient du fait que les classes n'étaient pas liées entre elles au moment de la compilation. Alors que les types sont vérifiés statiquement au moment de la compilation, différentes implémentations pour les classes peuvent être échangées juste avant l'exécution en écrasant simplement le fichier de classe. Tant que la nouvelle définition de classe avait les mêmes noms de classe et de méthode, le code fonctionnerait toujours. En ce sens, elle est similaire à la définition traditionnelle de la reliure tardive.

Actuellement, il est courant d'utiliser le terme liaison tardive dans la programmation Java comme synonyme de répartition dynamique . Plus précisément, cela fait référence au mécanisme de répartition unique de Java utilisé avec les méthodes virtuelles.

Enfin, Java peut utiliser la liaison tardive à l'aide de ses API de réflexion et de l' introspection de type de la même manière que dans la programmation COM et .NET. De manière générale, ceux qui ne programment qu'en Java n'appellent pas cette liaison tardive. De même, l'utilisation de techniques de « dactylographie » est désapprouvée dans la programmation Java, avec des interfaces abstraites utilisées à la place.

Oracle, le propriétaire actuel de Java, est connu pour utiliser le terme de liaison tardive dans le sens de "duck typing" lorsqu'il discute à la fois de Java et d'autres langages dans la même documentation.

Liaison précoce ou tardive en PL/SQL et Ada

Lors de l'utilisation d'une liaison anticipée entre Ada et une procédure stockée dans la base de données, un horodatage est vérifié pour vérifier que la procédure stockée n'a pas changé depuis la compilation du code. Cela permet des exécutions plus rapides et empêche l'application de s'exécuter sur la mauvaise version d'une procédure stockée.

Lors de l'utilisation de la liaison tardive, la vérification de l'horodatage n'est pas effectuée et la procédure stockée est exécutée via un bloc PL/SQL anonyme. Bien que cela puisse être plus lent, cela supprime le besoin de recompiler toutes les applications clientes lorsqu'une procédure stockée change.

Cette distinction semble être propre à PL/SQL et Ada. D'autres langages pouvant appeler des procédures PL/SQL, ainsi que d'autres moteurs de bases de données, n'utilisent que la liaison tardive.

Critique

La liaison tardive a des performances inférieures à celles d'un appel de méthode à liaison précoce. Dans la plupart des implémentations, l'adresse de méthode correcte doit être recherchée par son nom à chaque appel, ce qui nécessite une recherche dans le dictionnaire relativement coûteuse et peut-être une logique de résolution de surcharge, mais elle est généralement négligeable sur les ordinateurs modernes.

Pour certains compilateurs, une liaison tardive peut empêcher l'utilisation de la vérification de type statique. Lors d'un appel lié tardivement, le compilateur doit supposer que la méthode existe. Cela signifie qu'une simple faute d'orthographe peut provoquer une erreur d'exécution. L'exception exacte varie selon la langue, mais elle est généralement nommée quelque chose comme "Méthode non trouvée" ou "Méthode manquante". Les compilateurs modernes évitent cela en s'assurant que chaque appel possible doit avoir une implémentation lors de la compilation.

La liaison tardive peut empêcher les formes d' analyse statique nécessaires à un environnement de développement intégré (IDE). Par exemple, la fonction « aller à la définition » d'un IDE peut ne pas fonctionner sur un appel à liaison tardive, si l'IDE n'a aucun moyen de savoir à quelle classe l'appel peut faire référence. Un IDE moderne résout facilement ce problème, en particulier pour les langages orientés objet, car une méthode à liaison tardive spécifie toujours une interface ou une classe de base, où "aller à la définition" mène, et "trouver toutes les références" peut être utilisé pour trouver toutes les implémentations ou dépassements.

Un problème similaire est qu'un éventuel manque d'informations de typage peut empêcher la création de graphes de dépendances. Cependant, d'autres méthodes de programmation telles que les interfaces abstraites peuvent entraîner les mêmes problèmes. Un IDE moderne peut créer de tels graphes de dépendances aussi facilement qu'il gère "trouver toutes les références".

Voir également

Les références