La version PDF de PPT Download Adresse: http://www.slideshare.net/jbyjohnc/jqquerysummit-lagescale-javascript-application-architecture
Remarque: Pendant le processus de collation, j'ai constaté que les pensées de l'auteur étaient répétées, alors il en a supprimé certains. Si votre anglais est bon, veuillez lire directement le PPT anglais.
Voici les principaux chapitres de cet article:
1. Qu'est-ce que "JavaScript Large Program"?
2. Considérez l'architecture du programme actuelle
3. Considération à long terme
4. Brainstorm
5. Architecture suggérée
5.1 Motif de conception
5.1.1 Théorie des modules
5.1.1.1 Présentation
Mode de module 5.1.1.2
5.1.1.3 Taille d'auto-face de l'objet
5.1.1.4 Module CommonJS
5.1.2 Mode de façade
5.1.3 Mode médiateur
5.2 Appliquer à votre architecture
5.2.1 FACADE - Abstraction du noyau
5.2.2 Médiateur - Core du programme
5.2.3 Fonctionnement étroitement
6. Publier Pub / Sub Extension: Événements d'inscription automatique
7. Q&R
8. Remerciements
Qu'est-ce que "JavaScript Large Program"?
Avant de commencer, définissons ce qu'est un grand site JavaScript. De nombreux experts en développement JS expérimentés ont également été contestés. Certaines personnes disent que plus de 100 000 lignes de code JavaScript sont considérées comme grandes, et certaines personnes disent que le code JavaScript doit être de plus de 1 Mo. En fait, aucun d'eux n'est correct, car la quantité de code ne peut pas être mesurée comme le nombre de codes installés. De nombreux code JS triviaux peuvent facilement dépasser 100 000 lignes.
Ma définition de "Big" est la suivante. Bien que cela ne soit pas correct, il doit être relativement proche:
Je pense personnellement que les grands programmes JavaScript devraient être très importants et intégrer de nombreux efforts de développeurs exceptionnels pour traiter les données des poids lourds et les afficher au navigateur.
Passez en revue l'architecture du programme actuelle
Je ne peux pas souligner l'importance de ce problème. De nombreux développeurs expérimentés disent souvent: "Les modèles créatifs et de conception existants se déroulent très bien sur mon projet de taille moyenne précédente, donc il devrait être bien de les utiliser à nouveau dans un programme légèrement plus grand, non?", Il est vrai sur certains programmes, mais n'oubliez pas que, puisque c'est un grand programme, il devrait généralement y avoir de grandes préoccupations qui doivent être décomposées et prêtes à l'attention. J'explique brièvement comment il faut du temps pour revoir l'architecture du programme qui fonctionne depuis longtemps. Dans la plupart des cas, l'architecture de programme JavaScript actuelle devrait ressembler à ceci (notez qu'il s'agit d'une architecture JS, pas de ce que tout le monde appelle souvent ASP.NET MVC):
widgets personnalisés
modèles
vues
Contrôleurs
modèles
bibliothèques / kits d'outils
un noyau d'application.
Vous pouvez également encapsuler le programme en plusieurs modules seuls, ou utiliser d'autres modèles de conception, ce qui est génial, mais si ces structures représentent complètement votre architecture, il peut y avoir des problèmes potentiels. Jetons un coup d'œil à quelques points importants:
1. Combien de choses dans votre architecture peut être retirée et réutilisée immédiatement?
Y a-t-il des modules distincts qui ne dépendent pas d'un autre code? Est-ce autonome? Si je vais à la base de code que vous utilisez, puis sélectionnez quelques codes de module de module et mets-les sur une nouvelle page, peut-il être utilisé immédiatement? Vous pouvez dire que le principe est OK. Je vous suggère de planifier longtemps. Si votre entreprise a déjà développé de nombreux programmes importants, soudain, un jour, quelqu'un a dit que le module de chat dans ce projet était bon, sortons-le et mettons-le dans un autre projet. Pouvez-vous simplement l'utiliser sans modifier le code?
2. De combien de modules le système a-t-il besoin pour s'appuyer sur d'autres modules?
Tous les modules du système sont-ils étroitement couplés? Avant de prendre cette question comme préoccupation, je vais d'abord expliquer. Ce n'est pas que tous les modules ne doivent pas avoir de dépendances. Par exemple, une fonction à grains fins peut être étendue de la fonction de base. Mon problème est différent de cette situation. Je parle des dépendances avant différents modules fonctionnels. En théorie, tous les modules fonctionnels différents ne devraient pas avoir trop de dépendances.
3. Si quelque chose ne va pas avec une partie de votre programme, les autres parties fonctionneront-elles encore?
Si vous créez un programme similaire à Gmail, vous pouvez constater que de nombreux modules de Gmail sont chargés dynamiquement, tels que le module de chat de chat, qui n'est pas chargé lors de l'initialisation de la page, et même si une erreur se produit après le chargement, d'autres parties de la page peuvent être utilisées normalement.
4. Pouvez-vous tester vos modules d'une manière très simple?
Chacun de vos modules peut être utilisé sur de grands sites avec des millions d'utilisateurs, ou même plusieurs sites l'utilisent, de sorte que vos modules doivent faire du test, c'est-à-dire que, à l'intérieur ou à l'extérieur de l'architecture, ils devraient être testés très simplement, y compris la plupart des affirmations qui peuvent être adoptées dans différents environnements.
Considération à long terme
Lors de la structuration de grands programmes, la chose la plus importante est d'être tourné vers l'avant. Vous ne pouvez pas considérer la situation un mois ou un an plus tard. Vous devriez considérer la possibilité de changements dans une période plus longue? Les développeurs lient souvent le code des opérations DOM et le programme trop étroitement, bien qu'ils aient parfois encapsulé une logique séparée en différents modules. Réfléchissez à la raison pour laquelle ce n'est pas très bon à long terme.
Un de mes collègues a dit une fois qu'une architecture précise peut ne pas convenir à de futurs scénarios, et parfois c'est correct, mais lorsque vous devez le faire, vous paierez beaucoup d'argent. Par exemple, vous devrez peut-être choisir de remplacer Dojo, JQuery, Zepto et Yui pour certaines raisons de performance, de sécurité et de conception. Pour le moment, il y a un problème. La plupart des modules ont des dépendances, qui nécessitent de l'argent, du temps et des personnes, non?
Il est normal pour certains petits sites, mais les grands sites doivent fournir un mécanisme plus flexible sans se soucier de divers problèmes entre divers modules. Cela permet d'économiser de l'argent et du temps.
Pour résumer, pouvez-vous maintenant être sûr que vous pouvez remplacer certaines bibliothèques de classe sans réécrire l'intégralité du programme? Sinon, ce dont nous allons parler ci-dessous vous convient plus.
De nombreux développeurs JavaScript expérimentés ont donné quelques notes clés:
Justin Meyer, auteur de JavascriptMVC, a déclaré:
Le plus grand secret de la création de grands programmes est que vous ne construisez jamais de grands programmes, mais que vous divisez les programmes en petits modules pour rendre chaque petit module testable, de taille, puis les intégrer dans le programme.
Auteur de sites Web JavaScript haute performance Nicholas, Zakas:
"La clé est de reconnaître dès le début que vous ne savez pas comment cela se développera. Lorsque vous acceptez que vous ne savez pas tout, vous commencez à concevoir le système de manière défensive. Vous identifiez les domaines clés qui peuvent changer, ce qui est souvent très facile lorsque vous y consacrez un peu de temps. -
Beaucoup de problèmes de texte sont trop gênants. Pour résumer, tout peut être changé, il doit donc être abstrait.
Auteur fondamentale de JQuery Rebecca Murphey:
Plus la connexion entre chaque module est proche, moins elle est réutilisable, et plus la difficulté de le changer.
Les vues importantes ci-dessus sont les éléments fondamentaux de la construction de l'architecture et nous devons nous en souvenir tout le temps.
Brainstoral
Broissons. Nous avons besoin d'une architecture lâche, sans dépendances entre les modules, chaque module et programme communiquent, puis la couche intermédiaire prend le dessus et traite les messages correspondants.
Par exemple, si nous avons un JavaScript créant un programme de boulangerie en ligne, un module envoie un message qui pourrait y avoir "il y a 42 tours qui doivent être livrés". Nous utilisons différentes couches de calques pour traiter les messages envoyés par le module et effectuons les éléments suivants:
Les modules n'accèdent pas directement au noyau du programme
Les modules n'appellent pas directement et n'affectent pas d'autres modules
Cela nous empêchera de faire des erreurs dans tous les modules en raison d'erreurs dans un certain module.
Un autre problème est la sécurité. La situation réelle est que la plupart des gens ne pensent pas que la sécurité intérieure est un problème. Nous disons dans nos cœurs que les programmes sont construits par moi-même. Je sais lesquels sont publics et privés. Il n'y a aucun problème avec la sécurité, mais avez-vous un moyen de définir quel module accéder au cœur du programme? Par exemple, il y a un module de chat de chat que je ne veux pas qu'il appelle le module d'administration, ou je ne veux pas qu'il appelle un module avec des autorisations d'écriture DB, car il y a une fragilité entre elles et il est facile de provoquer des attaques XSS. Chaque module ne doit pas être en mesure de tout faire, mais le code JavaScript dans la plupart des architectures a actuellement ce problème. Fournissez une couche intermédiaire pour contrôler quel module peut accéder à cette partie autorisée, c'est-à-dire que le module ne peut obtenir que la majeure partie de la partie que nous avons autorisée.
Architecture suggérée
L'objectif de notre article est que cette fois l'architecture que nous proposons utilise des modèles de conception que nous sommes tous bien connus: module, façade et médiateur.
Contrairement aux modèles traditionnels, afin de découpler chaque module, nous n'avons laissé que le module publier certains événements d'événements. Le mode médiateur peut être responsable de l'abonnement aux messages de messages de ces modules, puis de contrôler la réponse de notification. Les utilisateurs de mode de façade restreignent les autorisations de chaque module.
Voici les pièces auxquelles nous devons prêter attention:
1 modèle de conception
1.1 Théorie des modules
1.1.1 Aperçu
1.1.2 Mode du module
1.1.3 Taille d'auto-visage des objets
1.1.4 Module CommonJS
1.2 mode de façade
1.3 Mode médiateur
2 Appliquer à votre architecture
2.1 FACADE - Abstraction du noyau
2.2 Médiateur - Core du programme
2.3 Travaillez en étroite collaboration
Théorie modale
Tout le monde a peut-être utilisé le code modulaire plus ou moins. Le module fait partie d'une architecture de programme complète et robuste. Chaque module est créé dans un but séparé. Pour en revenir à Gmail, prenons un exemple. Le module de chat de chat semble être une partie distincte, mais en fait, il a de nombreux sous-modules distincts. Par exemple, le module d'expression à l'intérieur est en fait un sous-module séparé, qui est également utilisé sur la fenêtre pour envoyer des e-mails.
Un autre est que les modules peuvent être chargés, supprimés et remplacés dynamiquement.
Dans JavaScript, nous avons plusieurs façons d'implémenter les modules. Tout le monde connaît les modèles de modules et les littéraux d'objets. Si vous les connaissez déjà, veuillez ignorer cette section et sauter directement à la partie CommonJS.
Mode module
Le motif du module est un modèle de conception relativement populaire. Il peut encapsuler des variables, des méthodes et des états privés à travers des accolades. En emballage ces contenus, les objets globaux ne sont généralement pas accessibles directement. Dans ce modèle de conception, une seule API est retournée et tous les autres contenus sont encapsulés comme privés.
De plus, ce modèle est similaire aux expressions de fonctions auto-exécutées. La seule différence est que le module renvoie un objet, tandis que l'expression de fonction auto-exécutée renvoie une fonction.
Comme nous le savons tous, JavaScript ne veut pas que d'autres langues aient des modificateurs d'accès et ne peuvent pas déclarer des modificateurs privés et publics pour chaque champ ou méthode. Alors, comment implémenter ce modèle? C'est pour renvoyer un objet, y compris certaines méthodes publiques, qui ont la possibilité d'appeler des objets internes.
Jetez un œil au code ci-dessous. Ce code est un code auto-exécutant. La déclaration comprend un objet global de batterie. Le tableau de panier est un privé, donc votre programme entier ne peut pas accéder à ce tableau privé. Dans le même temps, nous renvoyons un objet, qui contient 3 méthodes (telles que addItem, getItemCount, getTotal). Ces 3 méthodes peuvent accéder au tableau de panier privé.
var basketmodule = (function () {var panket = []; // privatereturn {// exposé à public additem: function (valeurs) {Basket.push (valeurs);}, getItemCount: function () {return Basket.length;}, getTotal: function () {var q = this.getItemCount (), p = 0; } return p;}}} ());Notez également que l'objet que nous retournons est attribué directement au basketmodule, afin que nous puissions l'utiliser comme ce qui suit:
// BasketModule est un objet avec des propriétés qui peuvent également être des méthodes BasketModule.additem ({item: 'pain', prix: 0,5}); basketmodule.additem ({article: 'beurre', prix: 0,3}); console.log (basketModule.getItemCount ()); console.log (basketmodule.getotal ()); // Cependant, ce qui suit ne fonctionnera pas: console.log (BasketModule.Basket); // (indéfini comme non à l'intérieur de l'objet retourné) Console.log (panier); // (n'existe que dans le cadre de la fermeture)Alors, comment le fait-il dans diverses bibliothèques de classe populaires (comme Dojo, JQuery)?
Dojo
Dojo tente d'utiliser Dojo.Declare pour fournir des méthodes de déclaration de style classe. Nous pouvons l'utiliser pour implémenter le modèle de module. Par exemple, si vous souhaitez déclarer un objet de panier sous l'espace de noms du magasin, vous pouvez le faire:
// Wayvar Store traditionnel = Window.Store || {}; store.basket = store.basket || {}; // Utilisation de dojo.setObjectDojo.SetObject ("Store.Basket.Object", (function () {var Basket = []; fonction privateMethod () {console.log (Basket);} return {publicMethod: function () {privateMethod ();}};} ()));Il est très puissant lorsqu'il est combiné avec Dojo.Provide.
Yui
Le code suivant est l'implémentation d'origine de YUI:
Yahoo.store.basket = function () {// "Private" Variables: var myprivatevar = "Je ne peux être accessible que dans yahoo.store.basket."; // Méthode "privé": var myprivateMethod = function () {yahoo.log ("je ne peux être accessible que dans yahoo.store.basket"); } return {myPublicProperty: "Je suis une propriété publique.", MyPublicMethod: function () {yahoo.log ("Je suis une méthode publique."); // Dans le panier, je peux accéder aux Vars et méthodes "privés": yahoo.log (myPrivateVar); Yahoo.log (myPrivateMethod ()); // La portée indigène de MyPublicMethod est le magasin afin que nous puissions // accéder aux membres publics en utilisant "this": yahoo.log (this.mypublicproperty); }};} ();jquery
Il existe de nombreuses implémentations du modèle de module dans jQuery. Jetons un coup d'œil à un exemple différent. Une fonction de bibliothèque déclare une nouvelle bibliothèque. Ensuite, lors de la création de la bibliothèque, la méthode init est automatiquement exécutée dans document.ready.
Fonction Library (module) {$ (function () {if (module.init) {module.init ();}}); module de retour;} var myLibrary = bibliothèque (function () {return {init: function () {/ * implémentation * /}};} ());Taille d'auto-face d'objet
La mesure d'auto-face de l'objet est déclarée en accolades et le nouveau mot-clé n'est pas requis lors de l'utilisation. Si vous ne vous souciez pas beaucoup du public / privé des champs d'attribut dans un module, vous pouvez utiliser cette méthode, mais veuillez noter que cette méthode est différente de JSON. Taille d'auto-face d'objet: var item = {name: "tom", valeur: 123} json: var item = {"name": "tom", "valeur": 123}.
var mymodule = {myProperty: 'SomeValue', // Les littéraux d'objet peuvent contenir des propriétés et des méthodes. // Ici, un autre objet est défini à des fins de configuration // MyConfig: {UseCaching: true, Language: 'en'}, // Une méthode très basique MyMethod: function () {console.log ('i Can Haz Functionality?'); }, // Sortie d'une valeur basée sur la configuration actuelle MyMethod2: function () {console.log ('Caching est:' + (this.myconfig.usecaching)? 'activé': 'désactivé'); }, // remplace la configuration actuelle myMethod3: function (newConfig) {if (typeof newConfig == 'Object') {this.myConfig = newConfig; console.log (this.myConfig.Language); }}}; mymodule.mymethod (); // je peux HAZ FonctionalityMyModule.myMethod2 (); // sorties activésMyModule.MyMethod3 ({Language: 'Fr', UseCaching: False}); // frCommonJS
Je ne parlerai pas de l'introduction de CommonJS ici. De nombreux articles l'ont déjà présenté. Ce que nous voulons mentionner ici, c'est qu'il existe deux exportations de paramètres importantes et nécessitent dans la norme CommonJS. Les exportations représentent le module à charger et nécessitent des moyens que ces modules chargés doivent s'appuyer sur d'autres modules et doivent également être chargés.
/ * Exemple de réalisation de la compatibilité avec AMD et standard CommonJS en mettant le chauffeur standard au format du module CommonJS standard: * / (fonction (define) {define (function (require, exports.SomeExportsFunction = function () {...}; // ...});}); Define == "fonction"? Define: function (factory) {factory (require, exports)});Il existe de nombreuses implémentations de chargement de modules standard CommonJS. Ce que je préfère, ce sont les exigences. Peut-il charger très bien les modules et les modules de dépendance connexes? Prenons un exemple simple. Par exemple, si vous avez besoin de convertir l'image en code ASCII, nous chargeons d'abord le module d'encodeur, puis obtenons sa méthode d'encodétoascii. Théoriquement, le code devrait être le suivant:
var encodetoascii = requis ("Encodeur"). Encodetoascii; export.encodesomesource = function () {// Après d'autres opérations, puis appelez encodetoascii}Cependant, le code ci-dessus ne fonctionne pas, car la fonction encodetoascii n'est pas utilisée pour se connecter à l'objet de fenêtre, donc il ne peut pas être utilisé. C'est ce que l'amélioration du code doit faire:
Define (fonction (require, exports, module) {var cocodetoascii = require ("encodeur"). Encodetoascii; exportS.Encodesomesource = function () {// procédé alors appelez encodetoascii}});CommonJS a un grand potentiel, mais comme l'oncle ne le connaît pas très bien, je ne le présenterai pas beaucoup.
Mode de façade
Le modèle de façade occupe un rôle important dans l'architecture de ce modèle. De nombreuses bibliothèques ou cadres de classe JavaScript se reflètent dans ce modèle. La plus grande fonction consiste à inclure l'API du niveau élevé pour masquer des implémentations spécifiques. Cela signifie que nous exposons uniquement les interfaces, et nous pouvons prendre par nous-mêmes les décisions des implémentations internes, ce qui signifie également que le code d'implémentation interne peut être facilement modifié et mis à jour. Par exemple, aujourd'hui, vous utilisez jQuery pour l'implémenter, et demain vous voulez changer Yui, ce qui est très pratique.
Dans l'exemple suivant, nous pouvons voir que nous fournissons de nombreuses méthodes privées, puis exposons une API simple pour permettre au monde extérieur d'exécuter et d'appeler les méthodes internes:
var module = (function () {var _private = {i: 5, get: function () {console.log ('valeur actuelle:' + this.i);}, set: function (val) {this.i = val;}, run: function () {console.log ('running');}, saut: function () {console.log ('saut'); fonction (args) {_private.set (args.val);La différence entre la façade et ce dont nous parlons ci-dessous est que la façade ne fournit que les fonctions existantes, tandis que les médiateurs peuvent ajouter de nouvelles fonctions.
Mode médiateur
Avant de parler du modificateur, donnons un exemple. Le système de commande de vol de l'aéroport, qui est la tour légendaire, a une puissance absolue. Il peut contrôler le décollage et l'atterrissage et le lieu de tout avion. L'avion et l'avion ne sont pas autorisés à communiquer auparavant, ce qui signifie que la tour est au cœur de l'aéroport, et le médiateur est équivalent à cette tour.
Le médiateur est utilisé pour avoir plusieurs modules dans un programme et vous ne voulez pas que chaque module ait des dépendances, alors le mode médiateur peut atteindre le but d'un contrôle centralisé. Dans les scénarios réels, le médiateur résume de nombreux modules qu'ils ne veulent pas faire, leur permettant d'être connectés par le biais de médiateurs, et les couplés de manière lâche, de sorte qu'ils doivent communiquer par le biais de médiateurs.
Alors, quels sont les avantages du mode médiateur? C'est le découplage. Si vous avez une bonne compréhension du modèle d'observateur auparavant, il sera relativement simple de comprendre le diagramme du médiateur ci-dessous. La figure suivante est un diagramme de motif de médiateur de haut niveau:
Pensez-y, chaque module est un éditeur, et le médiateur est à la fois un éditeur et un abonné.
Le module 1 diffuse une chose réelle au médiateur, disant que quelque chose doit être fait
Une fois que le médiateur a capturé le message, démarrez immédiatement le module 2 qui doit être utilisé pour traiter le message. Une fois le traitement du module 2 terminé, renvoyez les informations au médiateur.
Dans le même temps, Mediator démarre également le module 3 et se connecte automatiquement au module 3 lors de la réception du message de retour du module 2.
On peut voir qu'il n'y a pas de communication entre les modules. De plus, le médiateur peut également implémenter la fonction de surveillance de l'état de chaque module. Par exemple, s'il y a une erreur dans le module 3, le médiateur ne peut temporairement souhaiter que d'autres modules, puis redémarrer le module 3, puis continuer à s'exécuter.
Avec le recul, nous pouvons voir que l'avantage du médiateur est que le module couplé vaguement est contrôlé par le même médiateur. Le module n'a besoin que de diffuser et d'écouter des événements, et il n'y a pas besoin de connexion directe entre les modules. De plus, plusieurs modules peuvent être utilisés pour le traitement des informations à la fois, ce qui nous facilite également pour ajouter de nouveaux modules à la logique de contrôle existante à l'avenir.
Il est certain que comme tous les modules ne peuvent pas communiquer directement, il peut y avoir une légère baisse des performances en tout relativement, mais je pense que cela en vaut la peine.
Utilisons une démo simple basée sur l'explication ci-dessus:
var Mediator = (function () {var subscribe = function (canal, fn) {if (! mediator.Channels [canal]) mediator.channels [canal] = []; mediator.channels [canal] .push ({context: this, rappel: fn}); renvoie this;}, publish = function (channel) {if (! mediator.channels) [canal]) VaRevale; Array.prototype.slice.call (arguments, 1); Abonnez-vous: Abonnez-vous, installation: fonction (obj) {obj.subscribe = abonnez-vous;Ensuite, il y a 2 modules appelés:
// pub / sub sur un médiateur centralisé médiateur.name = "Tim"; médiateur.subscribe ('nameChange', function (arg) {console.log (this.name); this.name = arg; console.log (this.name);}); médiateur.publish ('namechange', 'david'); // Tim, David // pub / sub via le médiateur tiers var obj = {name: 'sam'}; mediator.installto (obj); obj.subscribe ('namechange', function (arg) {console.log (this.name); this.name = arg; console.log (this.name);}); obj.publish («namechange», «John»); // Sam, JohnFasade d'application: l'abstraction du cœur de l'application
Une façade fonctionne comme un résumé du noyau d'application et est responsable de la communication entre le médiateur et le module. Chaque module ne peut communiquer qu'avec le noyau du programme à travers cette façade. La responsabilité en tant que résumé est de s'assurer que ces modules peuvent être fournis avec une interface cohérente à tout moment, ce qui est similaire au rôle du contrôleur SendBox. Tous les composants du module communiquent avec les médiateurs à travers lui, donc la façade doit être fiable et digne de confiance. Dans le même temps, en fonction de fournir une interface au module, la façade doit jouer un autre rôle, c'est-à-dire le contrôle de sécurité, c'est-à-dire pour déterminer quelle partie du programme peut être accessible par un module. Les composants du module ne peuvent appeler que leurs propres méthodes et ne peuvent accéder à aucun contenu non autorisé. Par exemple, un module peut diffuser DataValidationCompletedWriteToDB, où les contrôles de sécurité doivent s'assurer que le module a des autorisations d'écriture dans la base de données.
En bref, le médiateur ne peut effectuer un traitement de l'information qu'après la détection d'autorisation de façade.
Médiateur d'application: le cœur de l'application
Le médiateur travaille comme un rôle principal pour l'application, parlons brièvement de ses responsabilités. Le travail le plus principal consiste à gérer le cycle de vie du module. Lorsque ce noyau capture des informations, elle doit juger de la façon dont le programme le gère - c'est-à-dire pour décider quel module démarrer ou arrêter. Lorsqu'un module démarre, il devrait être en mesure d'exécuter automatiquement, sans le noyau d'application pour décider s'il doit être exécuté (par exemple, s'il doit être exécuté lorsque Dom est prêt), donc le module lui-même doit déterminer.
Vous pouvez avoir une question, dans quelles circonstances un module s'arrêtera-t-il? Lorsque le programme détecte qu'un module échoue ou fait une erreur, le programme doit prendre une décision pour empêcher la méthode du module de continuer à s'exécuter afin que le composant puisse être redémarré, dans le but principal d'améliorer l'expérience utilisateur.
De plus, le noyau devrait être capable d'ajouter ou de supprimer dynamiquement les modules sans affecter d'autres fonctions. Un exemple courant est qu'un module n'est pas disponible au début du chargement de la page, mais après que l'utilisateur fonctionne, il doit charger dynamiquement le module puis l'exécuter. Tout comme la fonction de chat dans Gmail, il devrait être facile à comprendre dans le but de l'optimisation des performances.
La gestion des erreurs d'exception est également gérée par le noyau d'application. De plus, lorsque chaque module diffuse des informations, il diffuse également les erreurs du noyau afin que le noyau du programme puisse arrêter / redémarrer ces modules en fonction de la situation. Il s'agit également d'une partie très importante de l'architecture lâche. Nous n'avons pas besoin de changer manuellement de modules. Nous pouvons le faire en utilisant Publish / SBONNE via le médiateur.
Assembler
Chaque module contient diverses fonctions dans le programme. Lorsqu'ils ont des informations à traiter, ils émettent des informations en avisant le programme (c'est leur principale responsabilité). La section QA suivante a mentionné que les modules peuvent s'appuyer sur certaines méthodes de fonctionnement de l'outil DOM, mais elles ne devraient pas dépendre d'autres modules du système. Un module ne doit pas prêter attention au contenu suivant:
1. Quel objet ou module souscrit aux informations publiées par ce module
2. Ces objets sont-ils des objets côté client ou serveur
3. Combien d'objets se sont abonnés à vos informations
Le cœur de l'application d'abstraction de façade évite la communication directe entre les modules. Il s'abonne aux informations de chaque module et est également responsable de la détection d'autorisation, garantissant que chaque module a sa propre autorisation distincte.
Mediator (Application Core) utilise le mode médiateur pour jouer le rôle de Publish / Subcribe Manager, responsable de la gestion des modules et de l'exécution de démarrage / d'arrêt des modules, et peut charger et redémarrer dynamiquement les modules avec des erreurs.
Le résultat de cette architecture est qu'il n'y a pas de dépendance entre les modules, en raison des applications couplées vaguement, elles peuvent être facilement testées et maintenues, chaque module peut être facilement réutilisé dans d'autres projets, ou peut être ajouté et supprimé dynamiquement sans affecter le programme.
Publier Pub / Sub Extension: Enregistrement automatique des événements
En ce qui concerne l'enregistrement automatique des événements, certaines spécifications de dénomination doivent être suivies. Par exemple, si un module publie un événement nommé MessageUpdate, tous les modules avec la méthode MessageUpdate seront automatiquement exécutés. Il y a des avantages et des avantages et des inconvénients. Pour des méthodes de mise en œuvre spécifiques, vous pouvez voir un autre article de moi: la version Magic mise à niveau de JQuery Custom Binding.
QA
1. Est-il possible de ne pas utiliser de façade ou de mode sable similaire?
Bien que le plan de l'architecture propose que FACADE puisse implémenter des fonctions de vérification d'autorisation, il est en fait tout à fait possible que les médiateurs puissent le faire. Ce que l'architecture légère doit faire est presque la même, c'est-à-dire le découplage et la garantie que chaque module communique directement avec le cœur de l'application est bien.
2. Vous avez amélioré que le module ne puisse pas être directement dépendant. Cela signifie-t-il qu'il ne peut compter sur aucune bibliothèque tierce (comme jQuery).
Il s'agit en fait d'un problème bilatéral. Comme nous l'avons mentionné ci-dessus, un module peut avoir des sous-modules ou des modules de base, tels que des classes d'outils de fonctionnement DOM BASIC, etc. À ce niveau, nous pouvons utiliser la bibliothèque tierce, mais assurez-vous que nous pouvons facilement les remplacer.
3. J'aime cette architecture et je veux commencer à utiliser cette architecture. Y a-t-il des échantillons de code qui peuvent être utilisés pour faire référence?
J'ai l'intention de faire un échantillon de code pour votre référence, mais avant cela, vous pouvez vous référer au post-rédaction d'Andrew Burgees JavaScript.
4. Est-ce possible si le module doit communiquer directement avec le noyau d'application?
Techniquement, il n'y a aucune raison pour que les modules ne puissent pas communiquer directement avec le noyau d'application maintenant, mais pour la plupart des expériences d'application, elle n'est toujours pas autorisée. Depuis que vous avez choisi cette architecture, vous devez respecter les règles définies par l'architecture.
Remerciements
Grâce à Nicholas Zakas pour le post original, pour résumer les idées ensemble, à Andree Hansson pour une revue technique, à Rebecca Murphey, Justin Meyer, John Hann, Peter Michaux, Paul Irish et Alex Sexton, tous ont fourni beaucoup d'informations liées à cette session.