Lorsque j'apporte des modifications à de grands systèmes, je suis souvent confronté au problème selon lequel certaines fonctionnalités doivent obtenir des données d'une autre pièce, mais elles se trouvent dans différentes parties d'une arborescence d'appels profonde et ramifiée, pouvant éventuellement circuler dans des écouteurs d'événements, des appels différés, etc. De cette façon, un simple changement peut gonfler rapidement.
Une citation connexe du billet de blog de Yossi Kreinin à http://www.yosefk.com/blog/i-want-a-struct-linker.html :
Vous avez une sorte de structure de données que vous transmettez beaucoup. Bientôt, la chose la plus précieuse de la structure n'est pas les données qu'elle conserve, mais le fait qu'elle est disponible tout au long d'un flux de contrôle velu.
Les variables globales sont un moyen classique de laisser le code "crier" vers du code distant, mais elles sont connues pour être problématiques. Les variables à portée dynamique sont un moyen plus restreint, mais elles sont également problématiques.
Existe-t-il des recherches sur les langages de programmation visant à résoudre ce problème? Pouvons-nous faciliter l'ajout de flux de données imprévus à une grande base de code, tout en ayant des vérifications statiques, des tests unitaires faciles et d'autres avantages?
la source
Réponses:
Vous faites référence à CDI (Context Dependency Injection) AKA IoC (Inversion of Control). Java JSF et Spring Framework en sont quelques exemples. ASP.NET MVC a des plugins comme Unity. Javascript commence à avoir des structures organisées utilisant des bibliothèques comme RequireJS, qui a un comportement d'injection vu dans de nombreux frameworks JS modernes. C'est pour le câblage des applications locales et distantes.
Pour un couplage lâche entre les réseaux, les entreprises aiment utiliser les services Web avec SOAP, REST, AJAX ou les appels à distance réguliers avec RPC. En Java, vous pouvez utiliser JAX-WS ou .NET WCF pour créer des services distribués. Ensuite, vous les alignez dans un bus de service ou un "flux de données" à partir de n'importe quelle langue ou plate-forme en tant que client. Ruby, Python, Scala, Java, C #, ... n'importe quoi.
Le couplage lâche vous permet de diviser et de vaincre les problèmes, et les services sont souvent le point d'entrée d'une base de données pour extraire des données. En montant l'échelle, nous avons la bête appelée Message Queue. Cette route mène à des cadres de type entreprise et infrastructure.
Si votre projet n'insiste sur aucun réseau, cependant, il existe des langages comme Scala, Akka, NodeJS etc. qui sont conçus pour un flux de données élevé au sein d'une seule application. Ils fonctionnent également avec certaines ou toutes les technologies mentionnées précédemment pour des projets complexes. Par exemple, Scala peut être utilisé avec les services JAX-RS REST pour extraire une sorte de «données globales» d'une source de données et avoir Spring pour le câblage interne IoC. Il existe également de nombreux cadres d'exécution ou de workflow dans JBoss, .NET et les outils GUI comme MuleESB. En développement, Eclipse et Netbeans vous permettent de faire glisser et déposer des services dans un écran d'organigramme visuel.
Enfin, Java a toujours des beans Singleton. Pour ajuster vos méthodes au moment de l'exécution, utilisez des cadres de proxy ou de réflexion. Mais honnêtement, c'est le cas en 1999.
Si vous effectuez autant d'appels pour envoyer un message à un utilisateur en fonction de son fuseau horaire, à mon avis, il existe probablement un moyen en deux étapes pour obtenir le même effet que l'utilisateur voit. Mais oui, les frameworks CDI sont portés par les langages existants comme un manteau qui leur donne tous les pouvoirs flexibles que vous avez mentionnés. J'aime l'appeler subconscient de mon programme, en prenant soin du travail sale de manière transparente.
la source
La façon la plus simple de le faire à grande échelle est en fait d'utiliser une sorte d'API d'encapsulation de données. Cela peut être un magasin NoSQL ou un RDBMS encapsulé (ou il peut en fait être à la fois à des moments et à des endroits différents dans la même application - il n'y a aucune raison pour laquelle vous ne pouvez pas avoir un RDBMS gérant à long terme et une base de données NoSQL gérant le contrôle d'état à court terme). Il pourrait même s'agir d'une série d'objets singleton.
Vos structures de données peuvent ensuite être mises à disposition dans une sorte d'espace neutre, d'une manière quelque peu gérée. C'est l'approche que nous adoptons avec LedgerSMB (mais avec quelques variables semi-globales pour ce qui est essentiellement des singletons cachés, mais encore une fois ceux-ci sont gérés, nous avons choisi de cacher directement l'objet parce que cela rendait la gestion des variables un peu plus facile, mais il y a ensuite tous les 4).
Bien sûr, toute approche a des compromis et vous ne pouvez pas contourner ces compromis. La clé est de regarder quels sont les compromis (gestion vs performances vs propreté du code vs pièges de codage potentiels) et prendre une décision en fonction de ce qui est le mieux pour votre application.
la source
Si vous utilisez (ou citez) les mots
alors je suppose que votre code est vraiment un gâchis. Vous devez le laisser tomber immédiatement. Si vous utilisez la modularisation / séparation des préoccupations, il n'y a pas de "flux de contrôle velu". Votre code manque simplement de simplicité, ce qui est également inférable par le fait que vous avez fait référence à des variables globales :-).
la source