Nous sommes en train de changer la manière dont notre application AS3 se connecte à notre ordinateur et nous mettons en place un système REST pour remplacer notre ancien.
Malheureusement, le développeur qui a commencé le travail est maintenant en congé de maladie de longue durée et il m'a été remis. Je travaille avec ce logiciel depuis environ une semaine et je comprends le système, mais il y a une chose qui me préoccupe. Il semble y avoir beaucoup de passage de fonctions en fonctions. Par exemple, notre classe qui appelle nos serveurs prend une fonction qu’elle appellera et transmettra un objet à la fin du processus et lorsque les erreurs auront été gérées, etc.
Cela me donne ce "mauvais pressentiment" où je sens que c'est une pratique horrible et je peux penser à certaines raisons mais je veux une confirmation avant de proposer un remaniement du système. Je me demandais si quelqu'un avait une expérience de ce problème possible?
la source
Réponses:
Ce n'est pas un problème
C'est une technique connue. Ce sont des fonctions d'ordre supérieur (fonctions qui prennent des fonctions en tant que paramètres).
Ce type de fonction est également un élément de base de la programmation fonctionnelle et est largement utilisé dans des langages fonctionnels tels que Haskell .
De telles fonctions ne sont ni mauvaises ni bonnes - si vous n'avez jamais rencontré la notion et la technique, elles peuvent être difficiles à comprendre au début, mais elles peuvent être très puissantes et constituent un bon outil pour votre ceinture d'outils.
la source
Ils ne sont pas simplement utilisés pour la programmation fonctionnelle. Ils peuvent aussi être appelés callbacks :
Pensez au code asynchrone pendant une seconde. Vous transmettez une fonction qui, par exemple, envoie des données à l'utilisateur. Lorsque le code est terminé, vous appelez cette fonction avec le résultat de la réponse, qu'elle utilise ensuite pour renvoyer les données à l'utilisateur. C'est un changement de mentalité.
J'ai écrit une bibliothèque qui récupère les données Torrent de votre seedbox. Vous utilisez une boucle d'événement non bloquante pour exécuter cette bibliothèque et obtenir des données, puis les renvoyer à l'utilisateur (par exemple, dans un contexte websocket). Imaginez que vous ayez 5 personnes connectées dans cette boucle d’événements et l’une des demandes visant à obtenir le blocage des données torrent de quelqu'un. Cela bloquera toute la boucle. Vous devez donc penser de manière asynchrone et utiliser des rappels - la boucle continue de s'exécuter et le processus de "restitution des données à l'utilisateur" ne s'exécute que lorsque l'exécution de la fonction est terminée. Vous ne devez donc pas l'attendre. Feu et oublie.
la source
Ce n'est pas une mauvaise chose. En fait, c'est une très bonne chose.
Transférer des fonctions en fonctions est tellement important pour la programmation que nous avons inventé les fonctions lambda en abrégé. Par exemple, on peut utiliser des algorithmes lambdas avec C ++ pour écrire un code très compact, mais expressif, qui permet à un algorithme générique d’utiliser des variables locales et d’autres états pour effectuer des opérations telles que la recherche et le tri.
Les bibliothèques orientées objet peuvent également avoir des callbacks qui sont essentiellement des interfaces spécifiant un petit nombre de fonctions (idéalement une, mais pas toujours). On peut ensuite créer une classe simple qui implémente cette interface et transmettre un objet de cette classe à une fonction. C'est la pierre angulaire de la programmation événementielle , où le code de niveau cadre (peut-être même dans un autre thread) doit faire appel à un objet pour changer d'état en réponse à une action de l'utilisateur. L' interface ActionListener de Java en est un bon exemple.
Techniquement, un foncteur C ++ est également un type d’objet de rappel qui exploite le sucre syntaxique
operator()()
pour faire la même chose.Enfin, il existe des pointeurs de fonction de style C qui ne devraient être utilisés qu'en C. Je n'entrerai pas dans les détails, je les mentionnerai simplement pour être complet. Les autres abstractions mentionnées ci-dessus sont de loin supérieures et devraient être utilisées dans les langues qui les possèdent.
D'autres ont mentionné la programmation fonctionnelle et le fait que les fonctions de passage sont très naturelles dans ces langues. Les lambda et les rappels sont ce que les langages procéduraux et POO imitent, et ils sont très puissants et utiles.
la source
Comme déjà dit, ce n'est pas une mauvaise pratique. C'est simplement un moyen de découpler et de séparer la responsabilité. Par exemple, dans OOP, vous feriez quelque chose comme ceci:
La méthode générique consiste à déléguer une tâche spécifique - dont elle ne sait rien - à un autre objet implémentant une interface. La méthode générique ne connait que cette interface. Dans votre cas, cette interface serait une fonction à appeler.
la source
En général, il n'y a rien de mal à passer des fonctions à d'autres fonctions. Si vous passez des appels asynchrones et souhaitez utiliser le résultat, vous aurez besoin d'un mécanisme de rappel.
Il existe cependant quelques inconvénients potentiels des rappels simples:
Avec des services Web simples, votre façon de procéder fonctionne bien, mais il devient gênant si vous avez besoin d'une séquence d'appels plus complexe. Il y a quelques alternatives cependant. Avec JavaScript, par exemple, l'utilisation de promesses a évolué ( ce qui est génial avec les promesses javascript ).
Ils impliquent toujours de transmettre des fonctions à d'autres fonctions, mais les appels asynchrones renvoient une valeur qui prend un rappel plutôt que de le rappeler directement eux-mêmes. Cela donne plus de flexibilité pour composer ces appels ensemble. Quelque chose comme cela peut être implémenté assez facilement dans ActionScript.
la source