Préface
Dans ce chapitre, nous allons expliquer le quatrième chapitre de la mise en œuvre des cinq principaux principes de JavaScript solide, le principe de ségrégation de l'interface.
Texte anglais original: http://freshbrewedcode.com/derekgreeer/2012/01/08/solid-javascript-the-interface-segregation-pricciple/
Remarque: L'auteur de cet article est assez touchant, donc l'oncle est également déprimé de le comprendre. Il suffit de le lire comme vous le souhaitez, ne restez pas coincé dedans.
La description du principe de l'isolement de l'interface est:
La copie de code est la suivante:
Les clients ne doivent pas être obligés de dépendre des méthodes qu'ils n'utilisent pas.
Les clients ne doivent pas être obligés de compter sur les méthodes qu'ils n'utilisent pas.
Lorsque la méthode d'interface sur laquelle l'utilisateur dépend est uniquement utilisée par d'autres utilisateurs et ne l'utilise pas, elle doit implémenter ces interfaces. En d'autres termes, si un utilisateur s'appuie sur une interface qui n'est pas utilisée mais utilisée par d'autres utilisateurs, lorsque d'autres utilisateurs modifient l'interface, tous les utilisateurs qui s'appuient sur l'interface seront affectés. Cela viole évidemment le principe de l'ouverture et de la fermeture, et ce n'est pas ce que nous attendons.
Le principe du principe d'isolement de l'interface est quelque peu similaire à la responsabilité unique. Les deux sont utilisés pour agréger les responsabilités fonctionnelles. En fait, le FAI peut être compris pour convertir des programmes avec des responsabilités uniques en un objet avec une interface publique.
Interface JavaScript
Comment respecter ce principe sous JavaScript? Après tout, JavaScript n'a pas la fonction d'interfaces. Si l'interface est ce que nous voulons établir le contrat et le découple via des types abstraits fournis par une certaine langue, on peut dire que c'est OK, mais JavaScript a une autre forme d'interface. Dans les modèles de conception de livres, éléments des logiciels orientés objet réutilisables, nous avons trouvé la définition de l'interface:
http://www.amazon.com/design-tatterns-elements-reusable-object-oriedd/dp/0201633612
Toute opération déclarée par un objet contient un nom d'opération, un objet de paramètre et une valeur de retour de l'opération. Nous l'appelons la signature de l'opérateur.
Toutes les opérations déclarées dans un objet sont appelées l'interface de cet objet. L'interface d'un objet décrit toutes les informations de demande qui se produisent sur cet objet.
Peu importe si un langage fournit une construction distincte pour représenter une interface, tous les objets ont une interface implicite composée de toutes les propriétés et méthodes de l'objet. Reportez-vous au code suivant:
La copie de code est la suivante:
var exampleBinder = {};
exampleBinder.ModeloBserver = (function () {
/ * Variable privée * /
retour {
Observer: fonction (modèle) {
/ * Code * /
retourner NewModel;
},
onChange: fonction (rappel) {
/ * Code * /
}
}
}) ();
exampleBinder.ViewAdaptor = (function () {
/ * Variable privée * /
retour {
lier: fonction (modèle) {
/ * Code * /
}
}
}) ();
exampleBinder.bind = fonction (modèle) {
/ * Variable privée * /
exampleBinder.ModeLoBServer.Onchange (/ * callback de rappel * /);
var om = exampleBinder.ModeloBserver.Observe (modèle);
exampleBinder.ViewAdaptor.bind (OM);
retourner OM;
};
La bibliothèque de classe Binder ci-dessus implémente la liaison bidirectionnelle. L'interface publique exposée par cette bibliothèque de classe est la méthode Bind, où les fonctions de la notification de modification et de l'interaction de vue utilisées dans BIND sont implémentées par des objets séparés ModelObserver et ViewAdaptor, respectivement. Ces objets sont en quelque sorte la mise en œuvre spécifique de la méthode de liaison de l'interface publique.
Bien que JavaScript ne fournit pas de types d'interface pour prendre en charge les contrats d'objet, l'interface implicite de l'objet peut toujours être fournie aux utilisateurs du programme comme contrat.
FAI et JavaScript
Certaines des sous-sections dont nous discutons ci-dessous sont l'impact de la violation du principe d'isolement de l'interface en JavaScript. Comme on le voit ci-dessus, bien qu'il soit dommage de mettre en œuvre le principe de l'isolement de l'interface dans les programmes JavaScript, il n'est pas aussi puissant que les langages typés statiquement. Les caractéristiques linguistiques de JavaScript rendent parfois la soi-disant interface un peu antiadhésive.
La réalisation de la dépravation
Dans les langues dactylographiées statiquement, l'une des raisons de la violation des principes des FAI est la mise en œuvre dégénérée. Les méthodes définies dans toutes les interfaces de Java et C # doivent être implémentées. Si vous n'en avez besoin que quelques-uns, les autres méthodes doivent également être mises en œuvre (peuvent être implémentées par vide ou lançant des exceptions). Dans JavaScript, si seules certaines interfaces dans un objet sont nécessaires, elle ne peut pas résoudre le problème de l'implémentation dégénérée, bien qu'il ne soit pas nécessaire de forcer l'implémentation de l'interface ci-dessus. Cependant, cette mise en œuvre viole toujours le principe du remplacement de Richter.
La copie de code est la suivante:
var rectangle = {
zone: function () {
/ * Code * /
},
Draw: function () {
/ * Code * /
}
};
Var GeometryPlication = {
getLargeGrectangle: fonction (rectangles) {
/ * Code * /
}
};
var drawingApplication = {
drawrectangles: fonction (rectangles) {
/ * Code * /
}
};
Lorsqu'une alternative rectangulaire pour satisfaire le getLareGrectangle du nouvel objet GeometryApplication, il n'a besoin que de la méthode Rectangle Area (), mais il viole le LSP (car il ne peut pas utiliser la méthode de dessin qui ne peut être utilisée que dans la méthode des dirtangles).
Couplage statique
Une autre raison des violations des FAI dans les langues dactylographiées statiquement est le couplage statique. Dans les langues dactylographiées statiquement, les interfaces jouent un rôle majeur dans un programme de conception à couplage vague. Que ce soit dans un langage dynamique ou statique, un objet peut parfois devoir communiquer entre plusieurs utilisateurs du client (tels que l'état partagé). Pour les langages typés statiquement, la meilleure solution consiste à utiliser les interfaces de rôle, ce qui permet à l'utilisateur d'interagir avec l'objet (qui peut être nécessaire de jouer plusieurs rôles) comme son implémentation pour découpler l'utilisateur et un comportement non lié. Il n'y a pas de tel problème dans JavaScript, car les objets sont découplés par les avantages uniques des langues dynamiques.
Couplage sémantique
Une raison courante pour violer le FAI est à la fois les langues dynamiques et typées statiquement, qui est le couplage sémantique. Le couplage soi-disant sémantique est l'interdépendance, c'est-à-dire que le comportement d'un objet dépend d'un autre objet, ce qui signifie que si un utilisateur modifie l'un des comportements, il est susceptible d'affecter un autre utilisateur. Cela viole également le principe de la responsabilité unique. Ce problème peut être résolu par l'héritage et la substitution d'objets.
Évolutivité
Une autre raison du problème est une question d'évolutivité. Beaucoup de gens donneront des exemples sur le rappel pour démontrer l'évolutivité (comme les paramètres de rappel après le succès en Ajax). Si une telle interface a besoin d'une implémentation et qu'il existe de nombreuses méthodes familières ou de méthodes dans l'objet de cette implémentation, le FAI deviendra très important. C'est-à-dire que lorsqu'une interface d'interface devient une nécessité d'implémenter de nombreuses méthodes, sa mise en œuvre deviendra extrêmement complexe et peut amener ces interfaces à assumer une responsabilité non cadrante. C'est l'interface graisseuse que nous mentionnons souvent.
Résumer
Les caractéristiques du langage dynamique en JavaScript rendent notre implémentation d'interfaces antiadhésives moins influentes que les langages typés statiquement, mais le principe de l'isolement d'interface a toujours sa fonction dans le modèle de programmation JavaScript.