Rappel de service (de l\'informatique)

Dans la programmation par ordinateur , un rappel de service est le code exécutable qui est passé car un argument à l'autre code. Il permet à une couche plus basse de logiciel de d'appeler une sous-routine de (ou la fonction) définie dans une couche de plus haut niveau.

Habituellement, les débuts de code de plus haut niveau en appelant une fonction dans le code plus bas lui passant un indicateur ou la poignée à une autre fonction. Tandis que la fonction plus basse s'exécute, elle peut appeler passer-dans la fonction n'importe quel nombre de fois d'exécuter une certaine tâche secondaire. Dans un autre scénario, la fonction plus basse enregistre passer-dans la fonction en tant que traiteur de qui doit s'appeler asynchrone par le plus bas à un temps postérieur en réaction à quelque chose.

Un rappel de service peut être employé comme alternative plus simple au polymorphisme et au de programmation générique, parce que le comportement exact d'une fonction peut être dynamiquement déterminé en passant les indicateurs ou les poignées de fonction différente (pourtant compatible) à la fonction plus basse. Ceci peut être une technique très puissante pour la réutilisation de code de .

Motivation

Pour comprendre la motivation pour l'usage des rappels de service, considérer le problème d'effectuer une opération arbitraire sur chaque article dans une liste. Une approche est au réitèrent au-dessus de la liste, fonctionnant sur chaque objet. C'est la solution la plus commune dans la pratique, mais il n'est pas idéal ; le code pour contrôler l'iterator (par exemple, un rapport de for) doit être reproduit à chaque point dans le code où la liste est traversée. En outre, si la liste est mise à jour par un processus asynchrone (par exemple, si un article est ajouté ou enlevé), l'iterator pourrait sauter au-dessus des articles ou devenir corrompu pendant le traversal.

Une alternative pourrait être de créer une nouvelle fonction de la bibliothèque qui effectue l'opération désirée avec la synchronisation appropriée. Cette approche exige toujours de chaque nouvelle fonction de bibliothèque de contenir le code pour traverser la liste. Cette solution n'est pas acceptable pour les bibliothèques génériques destinées à de diverses applications ; le lotisseur de bibliothèque ne peut pas prévoir chaque besoin d'application, et le créateur d'application ne devrait pas devoir connaître les détails de l'exécution de bibliothèque.

Les rappels de service résolvent ces points faibles. Un procédé est écrit pour traverser la liste, et les utilisations de ce procédé application-ont fourni le code pour opérer chaque article. Il y a une distinction claire entre la bibliothèque et l'application sans sacrifier la flexibilité.

Un rappel de service peut également être considéré comme une forme de d'exécution liant , comme discuté dans le livre influent des modèles de conception de (voir le résumé du chapitre 1).

Exemple

Le code suivant dans le C démontre l'utilisation des rappels de service pour le cas spécifique de rechercher une rangée un article (dans ce cas-ci, le premier nombre entier plus considérablement que 5). D'abord, l'approche d'itération :

lang=" de international i ; pour (I = 0 ; i < longueur ; i++) { si (rangée > 5) { coupure ; } } si (I < longueur) { printf (" ; Article %d \ n" ; , i) ; } autrement { printf (" ; Non trouvé \ n" ;); }

Après, l'approche de rappel de service :

lang=" de CODE DE BIBLIOTHÈQUE DE/* * traverseWith d'international (rangée d'international, longueur de size_t, international (*callback) (index d'international, article d'international, *param vide), *param vide) { exitCode d'international = 0 ; pour (international i = 0 ; i < longueur ; i++) { exitCode = rappel de service (I, rangée, param) ; si (exitCode ! = 0) { coupure ; } } exitCode de retour ; } CODE D'APPLICATION DE/* * recherche d'international (index d'international, article d'international, *param vide) { si (article > 5) { * (international *) param = index ; retour 1 ; } autrement { retour 0 ; } } /* (dans une autre fonction) * index d'international ; l'international a trouvé ; trouvé = traverseWith (rangée, longueur, &search, &index) ; si (trouvé) { printf (" ; Article %d \ n" ; , index) ; } autrement { printf (" ; Non trouvé \ n" ;); }

Noter que le traverseWith reçoit un paramètre supplémentaire que le rappel de service peut employer pour ses propres buts. Normalement un rappel de service emploie un paramètre tel qu'un indicateur aux données d'application en dehors de sa propre portée (dans ce cas-ci, la variable qui reçoit l'index). Ce dispositif est nécessaire seulement dans une langue statiquement scoped comme C ou C++ (dans des langues de C++ et d'OO d'autres solutions sont cependant possibles, voient ci-dessous). Les langues dynamiquement scoped (langages de programmation fonctionnelle y compris) peuvent permettre d'accéder aux données d'application automatiquement par l'intermédiaire des fermetures . Dans le blèsent , par exemple, le même programme ressemblerait à ceci :

lang=" de ; CODE DE BIBLIOTHÈQUE (traverseWith de defun (rappel de service de rangée) (laisser ((zéro d'exitCode) (I 0)) (tandis que (et (pas exitCode) (< I (rangée de longueur))) (exitCode de setq (rappel de service i (rangée d'aref i))) (setq i (+ I 1))) exitCode)) ; CODE D'APPLICATION (laisser (l'index fonder) (le setq a trouvé (rangée de traverseWith (lambda (article d'idx) (si (zéro de point de <= 5) (idx d'index de setq) t)))))

La fonction de rappel de service est maintenant définie au moment où l'utilisation, et elle se rapporte au " ; index" ; de nom. Des soucis de synchronisation ont été omis de ces exemples, mais ils peuvent facilement être adressés dans la fonction de traverseWith. D'une manière primordiale, ils peuvent être adressés, ou ignorés, en changeant seulement cette fonction.

Exécution

La forme d'un rappel de service varie parmi les langages de programmation
le C de

et le C++ permettent les indicateurs de fonction de comme arguments à d'autres fonctions.
Plusieurs langages de programmation (cependant particulièrement langages de programmation fonctionnelle tel qu'arrangement ou ml ) permettent les fermetures , une généralisation de des indicateurs de fonction, comme arguments à d'autres fonctions.
Plusieurs langages de programmation, particulièrement les langues interprétées permettent à on de passer le nom de d'une fonction A comme paramètre à une fonction B et d'avoir l'appel A de B au moyen de Eval .
Dans les langages de programmation orientée objectivement un appel peut accepter un objet qui met en application une certaine interface abstraite, sans spécifier en détail comment l'objet devrait faire ainsi. Le programmeur qui met en application cet objet peut employer les méthodes de l'interface exclusivement pour le code spécifique à l'application. De tels objets sont effectivement un paquet de rappels de service, plus les données qu'ils doivent manoeuvrer. Ils sont utiles en mettant en application les divers modèles de conception de comme le visiteur , l'observateur , et la stratégie .
C++ permet à des objets de fournir leur propre exécution de l'opération d'appel de fonction. La bibliothèque standard de calibre de accepte ces objets (appelés les functors de ), aussi bien que des indicateurs de fonction, comme paramètres à de divers algorithmes polymorphes
Quelques systèmes ont des langages de programmation intégrés pour soutenir la prolongation et l'adaptation. Ces langues fournissent des rappels de service sans besoin d'instruments de développement séparés de logiciel.

Cas spéciaux

Des fonctions de rappel de service sont également fréquemment employées en tant que des moyens de manipuler des exceptions surgissant dans la fonction de bas niveau, comme manière de permettre les effets secondaires en réponse à une certaine condition, ou comme manière de recueillir des statistiques opérationnelles au cours d'un plus grand calcul. Les traiteurs d'interruption dans un du système d'exploitation répondent aux états de matériel, les traiteurs de signal de d'un processus sont déclenchés par le du système d'exploitation, et procédé des traiteurs d'événement l'entrée asynchrone qu'un programme reçoit.

Une fonction de rappel de service pure de est un qui est le purement fonctionnel (renvoie toujours la même valeur donnée les mêmes entrées) et exempt des effets secondaires observables. Quelques utilisations des rappels de service, tels que l'exemple de tri, exigent des fonctions de rappel de service pures de fonctionner correctement.

Un cas spécial d'un rappel de service s'appelle un rappel de service d'attribut de , ou juste l'attribut pour le short. C'est une fonction de rappel de service pure qui accepte une valeur à entrée unique et renvoie une valeur booléenne du . Ces types de rappels de service sont utiles pour filtrer des collections de valeurs par une certaine condition.

Dans la programmation entraînée par les événements , il y a souvent utilisation, dans différentes formes, du modèle d'observateur de , qui permet essentiellement l'utilisation des rappels de service de multicast, et d'où les rappels de service sont enregistrés par tôt, être appelé à la discrétion de l'appelé (c. quand un événement donné se produit). Quelques langages de programmation ont également le soutien direct de cette construction (par exemple le de .NET délègue signaux de ou le de s de quart des 'et raine ).

Voir également

Signaux et fentes
Libsigc++ , une bibliothèque de rappel de service pour C++
Invocation implicite
Procédure utilisateur

.

Random links:Sushun | 1949 en Irlande | Ramón Cabrera | Philippines aux 1968 Jeux Olympiques d'été | La publicité d'enveloppe | Servicio_repetido_(de_informática)