Je n'arrive pas à comprendre le concept de «couplage lâche». Je suppose que cela n'aide pas que le mot «lâche» ait généralement une connotation négative, alors j'oublie toujours qu'un couplage lâche est une bonne chose.
Quelqu'un voudra-t-il montrer du code «avant» et «après» (ou pseudocode) qui illustre ce concept?
oop
language-agnostic
loose-coupling
trebormf
la source
la source
Réponses:
Considérez une application de panier simple qui utilise une classe CartContents pour garder une trace des articles dans le panier et une classe Order pour traiter un achat. La commande doit déterminer la valeur totale du contenu du panier, elle pourrait le faire comme ceci:
Exemple étroitement couplé:
Notez comment la méthode OrderTotal (et donc la classe Order) dépend des détails d'implémentation des classes CartContents et CartEntry. Si nous devions essayer de changer cette logique pour permettre des remises, nous devrons probablement changer les 3 classes. De plus, si nous passons à l'utilisation d'une collection List pour garder une trace des éléments, nous devrons également modifier la classe Order.
Voici maintenant une meilleure façon de faire la même chose:
Exemple moins couplé:
La logique spécifique à la mise en œuvre de l'élément de campagne du panier ou de la collecte du panier ou de la commande est limitée à cette seule classe. Nous pourrions donc changer l'implémentation de l'une de ces classes sans avoir à changer les autres classes. Nous pourrions pousser encore plus loin ce découplage en améliorant la conception, en introduisant des interfaces, etc., mais je pense que vous voyez le point.
la source
Order
ait la moindre connaissance d'unCart
. Les achats en direct et la facturation sont deux contextes différents. Lorsque le client est prêt à payer, vous pouvez avoir un processus chargé de traduire les CartEntries en quelque chose de signifiant pour leOrder
. De cette façon, laOrder
classe serait également instanciée et utilisée sansCart
.CartEntry
etCartContents
. Comme ceux-ci ont une signification parfaitement claire, ils doivent être simplement modélisés comme des données mortes. en termes de base de données, il suffit ici d'une tableCREATE TABLE entry (price INTEGER, quantity INTEGER)
De nombreux produits intégrés (en particulier par Apple) tels que les iPod , les iPad sont un bon exemple de couplage serré: une fois que la batterie est épuisée, vous pouvez aussi bien acheter un nouvel appareil car la batterie est soudée fixe et ne se détache pas, ce qui rend le remplacement très coûteux. Un lecteur faiblement couplé permettrait de changer sans effort la batterie.
Il en va de même pour le développement logiciel: il est généralement (beaucoup) préférable d'avoir un code faiblement couplé pour faciliter l'extension et le remplacement (et pour rendre les différentes parties plus faciles à comprendre). Mais, très rarement, dans des circonstances particulières, un couplage étroit peut être avantageux car l'intégration étroite de plusieurs modules permet une meilleure optimisation.
la source
J'utiliserai Java comme exemple. Disons que nous avons une classe qui ressemble à ceci:
Lorsque j'appelle la classe, je dois faire quelque chose comme ceci:
Jusqu'ici tout va bien. Maintenant, disons que j'ai une autre classe qui ressemble à ceci:
Cela ressemble exactement à ABC, mais disons que cela fonctionne sur le réseau plutôt que sur le disque. Alors maintenant, écrivons un programme comme celui-ci:
Cela fonctionne, mais c'est un peu difficile à manier. Je pourrais simplifier cela avec une interface comme celle-ci:
Maintenant, mon code peut ressembler à ceci:
Voyez à quel point c'est plus propre et plus simple à comprendre? Nous venons de comprendre le premier principe de base du couplage lâche: l'abstraction. La clé ici est de s'assurer que ABC et XYZ ne dépendent d'aucune méthode ou variable des classes qui les appellent. Cela permet à ABC et XYZ d'être des API totalement indépendantes. Ou en d'autres termes, ils sont "découplés" ou "faiblement couplés" des classes parentes.
Mais que faire si nous avons besoin d'une communication entre les deux? Eh bien, nous pouvons utiliser d'autres abstractions comme un modèle d'événement pour nous assurer que le code parent n'a jamais besoin de se coupler avec les API que vous avez créées.
la source
DiskAccessor
etNetworkAccessor
? Je ne sais pas java ...Désolé, mais «couplage lâche» n'est pas un problème de codage, c'est un problème de conception. Le terme «couplage lâche» est intimement lié à l'état souhaitable de «cohésion élevée», étant opposé mais complémentaire.
Un couplage lâche signifie simplement que des éléments de conception individuels doivent être construits afin de réduire la quantité d'informations inutiles dont ils ont besoin sur d'autres éléments de conception.
Une cohésion élevée est un peu comme un «couplage serré», mais une cohésion élevée est un état dans lequel les éléments de conception qui ont vraiment besoin de se connaître sont conçus pour qu'ils fonctionnent ensemble proprement et élégamment.
Le fait est que certains éléments de conception doivent connaître des détails sur d'autres éléments de conception, ils doivent donc être conçus de cette façon, et non par accident. Les autres éléments de conception ne doivent pas connaître les détails des autres éléments de conception, ils doivent donc être conçus de cette manière, à dessein, plutôt que de manière aléatoire.
La mise en œuvre est laissée comme un exercice pour le lecteur :).
la source
Un code étroitement couplé repose sur une implémentation concrète. Si j'ai besoin d'une liste de chaînes dans mon code et que je la déclare comme ceci (en Java)
alors je suis dépendant de l'implémentation ArrayList.
Si je veux changer cela en code faiblement couplé, je fais de ma référence un type d'interface (ou autre abstrait).
Cela m'empêche d'appeler une méthode
myList
spécifique à l'implémentation ArrayList. Je suis limité aux seules méthodes définies dans l'interface de liste. Si je décide plus tard que j'ai vraiment besoin d'une LinkedList, je n'ai besoin de changer mon code qu'à un seul endroit, où j'ai créé la nouvelle List, et pas à 100 endroits où j'ai fait des appels aux méthodes ArrayList.Bien sûr, vous pouvez instancier une ArrayList en utilisant la première déclaration et vous empêcher de n'utiliser aucune méthode qui ne fait pas partie de l'interface List, mais l'utilisation de la deuxième déclaration permet au compilateur de vous garder honnête.
la source
Le degré de différence entre les réponses montre ici pourquoi ce serait un concept difficile à saisir mais pour le dire aussi simplement que je peux le décrire:
Pour que je sache que si je te lance une balle, tu peux l'attraper, je n'ai vraiment pas besoin de savoir quel âge tu as. Je n'ai pas besoin de savoir ce que tu as mangé au petit-déjeuner, et je me fiche de qui était ton premier béguin. Tout ce que j'ai besoin de savoir, c'est que vous pouvez attraper. Si je le sais, alors je m'en fiche si c'est toi que je te lance une balle ou à ton frère.
Avec des langages non dynamiques comme c # ou Java, etc., nous y parvenons via des interfaces. Disons donc que nous avons l'interface suivante:
Et maintenant, disons que nous avons les classes suivantes:
À présent, CatcherA et CatcherB implémentent la méthode Catch, de sorte que le service qui nécessite un Catcher peut utiliser l'un ou l'autre de ces derniers et ne pas vraiment se tromper de quel il s'agit. Ainsi, un service étroitement couplé pourrait directement instancier un ie
Ainsi, le CatchService peut faire exactement ce qu'il a prévu de faire, mais il utilise CatcherA et utilisera toujours CatcherA. Il est codé en dur, donc il reste là jusqu'à ce que quelqu'un vienne le refactoriser.
Prenons maintenant une autre option, appelée injection de dépendances:
Ainsi, les cals qui instanment CatchService peuvent effectuer les opérations suivantes:
ou
Cela signifie que le service Catch n'est pas étroitement couplé à CatcherA ou CatcherB.
Il existe plusieurs autres stratégies pour coupler de manière lâche des services comme celui-ci, comme l'utilisation d'un framework IoC, etc.
la source
Vous pouvez penser au couplage (serré ou lâche) comme étant littéralement la quantité d'effort qu'il vous faudrait pour séparer une classe particulière de sa dépendance à une autre classe. Par exemple, si chaque méthode de votre classe avait un petit bloc final en bas où vous avez appelé Log4Net pour enregistrer quelque chose, alors vous diriez que votre classe était étroitement couplée à Log4Net. Si votre classe contenait à la place une méthode privée nommée LogSomething qui était le seul endroit qui appelait le composant Log4Net (et les autres méthodes toutes appelées LogSomething à la place), alors vous diriez que votre classe était vaguement couplée à Log4Net (car cela ne prendrait pas beaucoup effort pour retirer Log4Net et le remplacer par autre chose).
la source
64BitBob
mieux la réponse de moi-même.Définition
Essentiellement, le couplage est la mesure dans laquelle un objet donné ou un ensemble d'objets dépend d'un autre objet ou d'un autre ensemble d'objets pour accomplir sa tâche.
Couplage élevé
Pensez à une voiture. Pour que le moteur démarre, une clé doit être insérée dans le contact, tournée, de l'essence doit être présente, une étincelle doit se produire, les pistons doivent tirer et le moteur doit prendre vie. On pourrait dire qu'un moteur de voiture est fortement couplé à plusieurs autres objets. C'est un couplage élevé, mais ce n'est pas vraiment une mauvaise chose.
Couplage lâche
Pensez à un contrôle utilisateur pour une page Web qui est chargé d'autoriser les utilisateurs à publier, modifier et afficher certains types d'informations. Le contrôle unique peut être utilisé pour permettre à un utilisateur de publier une nouvelle information ou de modifier une nouvelle information. Le contrôle doit pouvoir être partagé entre deux chemins différents - nouveau et édition. Si le contrôle est écrit de telle manière qu'il a besoin d'un type de données provenant des pages qui le contiendront, alors vous pourriez dire qu'il est trop fortement couplé. Le contrôle ne doit pas avoir besoin de quoi que ce soit de sa page conteneur.
la source
C'est un concept assez général, donc les exemples de code ne donneront pas une vue d'ensemble.
Un gars ici au travail m'a dit: "Les motifs sont comme des fractales, vous pouvez les voir lorsque vous zoomez très près et lorsque vous effectuez un zoom arrière au niveau de l'architecture."
La lecture de la brève page wikipedia peut vous donner une idée de cette généralité:
http://en.wikipedia.org/wiki/Loose_coupling
En ce qui concerne un exemple de code spécifique ...
Voici un couplage lâche avec lequel j'ai travaillé récemment, du truc Microsoft.Practices.CompositeUI.
Ce code déclare que cette classe a une dépendance sur un CustomizableGridService. Au lieu de simplement référencer directement l'implémentation exacte du service, il indique simplement qu'il nécessite une implémentation de ce service. Ensuite, au moment de l'exécution, le système résout cette dépendance.
Si ce n'est pas clair, vous pouvez lire une explication plus détaillée ici:
http://en.wikipedia.org/wiki/Dependency_injection
Imaginez que ABCCustomizableGridService est l'implémentation que j'ai l'intention de connecter ici.
Si je le souhaite, je peux retirer cela et le remplacer par XYZCustomizableGridService ou StubCustomizableGridService sans aucune modification de la classe avec cette dépendance.
Si j'avais directement référencé ABCCustomizableGridService, alors je devrais apporter des modifications à cette / ces référence / s afin de permuter dans une autre implémentation de service.
la source
Le couplage concerne les dépendances entre les systèmes, qui peuvent être des modules de code (fonctions, fichiers ou classes), des outils dans un pipeline, des processus serveur-client, etc. Moins les dépendances sont générales, plus elles deviennent "étroitement liées", car changer un système nécessitait de changer les autres systèmes qui en dépendent. La situation idéale est un «couplage lâche» où un système peut être changé et les systèmes qui en dépendent continueront à fonctionner sans modification.
La manière générale d'obtenir un couplage lâche consiste à utiliser des interfaces bien définies. Si l'interaction entre deux systèmes est bien définie et respectée des deux côtés, il devient alors plus facile de modifier un système tout en s'assurant que les conventions ne sont pas rompues. Il arrive généralement en pratique qu'aucune interface bien définie ne soit établie, ce qui entraîne une conception bâclée et un couplage serré.
Quelques exemples:
L'application dépend d'une bibliothèque. Sous un couplage étroit, l'application est interrompue sur les nouvelles versions de la bibliothèque. Google pour "DLL Hell".
L'application client lit les données d'un serveur. Sous un couplage étroit, les modifications apportées au serveur nécessitent des correctifs côté client.
Deux classes interagissent dans une hiérarchie orientée objet. En cas de couplage étroit, les modifications apportées à une classe nécessitent que l'autre classe soit mise à jour pour correspondre.
Plusieurs outils de ligne de commande communiquent dans un canal. S'ils sont étroitement couplés, les modifications apportées à la version d'un outil de ligne de commande entraîneront des erreurs dans les outils qui liront sa sortie.
la source
Le couplage fait référence à la manière dont les classes sont étroitement liées les unes aux autres. Les classes étroitement couplées contiennent un nombre élevé d'interactions et de dépendances.
Les classes faiblement couplées sont le contraire en ce que leurs dépendances les unes des autres sont réduites au minimum et reposent plutôt sur les interfaces publiques bien définies les unes des autres.
Legos, les jouets qui S'AGRAMMENT ensemble seraient considérés comme faiblement couplés parce que vous pouvez simplement assembler les pièces et construire le système que vous voulez. Cependant, un puzzle a des pièces qui sont étroitement couplées. Vous ne pouvez pas prendre une pièce d'un puzzle (système) et l'enclencher dans un puzzle différent, car le système (puzzle) est très dépendant des pièces très spécifiques qui ont été construites spécifiquement pour cette «conception» particulière. Les legos sont construits de manière plus générique afin qu'ils puissent être utilisés dans votre Lego House, ou dans mon Lego Alien Man.
Référence: https://megocode3.wordpress.com/2008/02/14/coupling-and-cohesion/
la source
Deux composants sont fortement couplés lorsqu'ils dépendent d'une mise en œuvre concrète l'un de l'autre.
Supposons que j'ai ce code quelque part dans une méthode de ma classe:
Maintenant, ma classe dépend de SomeObject, et ils sont fortement couplés. D'un autre côté, disons que j'ai une méthode InjectSomeObject:
Ensuite, le premier exemple peut simplement utiliser SomeObject injecté. Ceci est utile lors des tests. Avec un fonctionnement normal, vous pouvez utiliser des classes lourdes, utilisant une base de données, utilisant le réseau, etc., tandis que pour les tests réussissant une implémentation légère et simulée. Avec un code étroitement couplé, vous ne pouvez pas faire cela.
Vous pouvez simplifier certaines parties de ce travail en utilisant des conteneurs d'injection de dépendances. Vous pouvez en savoir plus sur DI sur Wikipedia: http://en.wikipedia.org/wiki/Dependency_injection .
Il est parfois facile d'aller trop loin. À un moment donné, vous devez rendre les choses concrètes, sinon votre programme sera moins lisible et compréhensible. Utilisez donc ces techniques principalement à la limite des composants et sachez ce que vous faites. Assurez-vous de profiter d'un couplage desserré. Sinon, vous n'en avez probablement pas besoin à cet endroit. DI peut rendre votre programme plus complexe. Assurez-vous de faire un bon compromis. En d'autres termes, maintenez un bon équilibre. Comme toujours lors de la conception de systèmes. Bonne chance!
la source
Considérez une application Windows avec FormA et FormB. FormA est le formulaire principal et il affiche FormB. Imaginez que FormB ait besoin de renvoyer des données à son parent.
Si vous avez fait ceci:
FormB est étroitement couplé à FormA. FormB ne peut avoir d'autre parent que celui de type FormA.
Si, en revanche, vous demandez à FormB de publier un événement et que FormA s'abonne à cet événement, alors FormB peut renvoyer les données via cet événement à n'importe quel abonné de cet événement. Dans ce cas, FormB ne sait même pas qu'il répond à son parent; grâce au couplage lâche que l'événement fournit, il parle simplement aux abonnés. Tout type peut désormais être parent de FormA.
rp
la source
En informatique, il y a une autre signification pour "couplage lâche" que personne d'autre n'a publié ici, alors ... Voilà - j'espère que vous me donnerez quelques votes pour que ce ne soit pas perdu au fond du tas! Sûrement le sujet de ma réponse appartient à toute réponse complète à la question ... À savoir:
Le terme "Loose Coupling" est entré pour la première fois dans le calcul comme un terme utilisé comme adjectif concernant l'architecture CPU dans une configuration multi-CPU. Son homologue est «couplage serré». Le couplage lâche se produit lorsque les processeurs ne partagent pas beaucoup de ressources en commun et le couplage serré le fait.
Le terme «système» peut prêter à confusion ici, veuillez donc analyser attentivement la situation.
Habituellement, mais pas toujours, plusieurs processeurs dans une configuration matérielle dans laquelle ils existent dans un système (comme dans des boîtiers "PC" individuels) seraient étroitement couplés. À l'exception de certains systèmes à très haute performance qui ont des sous-systèmes qui partagent en fait la mémoire principale entre les «systèmes», tous les systèmes divisibles sont faiblement couplés.
Les termes Tightly Coupled et Loosely Coupled ont été introduits avant invention des processeurs multi-thread et multi-core, donc ces termes peuvent nécessiter des compagnons pour articuler pleinement la situation actuelle. Et, en effet, aujourd'hui, on peut très bien avoir un système qui englobe les deux types dans un système global. En ce qui concerne les systèmes logiciels actuels, il existe deux architectures communes, une de chaque variété, qui sont suffisamment communes pour qu'elles soient familières.
Premièrement, comme c'était le sujet de la question, quelques exemples de systèmes à couplage lâche:
En revanche, quelques exemples étroitement couplés:
Dans l'informatique d'aujourd'hui, les exemples des deux fonctionnant dans un seul système global ne sont pas rares. Par exemple, prenez les processeurs Pentium double ou quadricœur modernes exécutant Fedora 9 - ce sont des systèmes informatiques étroitement couplés. Ensuite, combinez plusieurs d'entre eux dans un cluster Linux faiblement couplé et vous avez maintenant un calcul à la fois lâche et étroitement couplé! Oh, le matériel moderne n'est-il pas merveilleux!
la source
Dans un langage simple, couplé de manière lâche signifie qu'il ne dépend pas d'un autre événement. Il s'exécute indépendamment.
la source
Quelques longues réponses ici. Le principe est cependant très simple. Je soumets la déclaration liminaire de wikipedia :
«Le couplage lâche décrit une relation résiliente entre deux ou plusieurs systèmes ou organisations avec une sorte de relation d'échange.
Chaque extrémité de la transaction rend ses exigences explicites et fait peu d'hypothèses sur l'autre extrémité.
la source
Je propose un test très simple de couplage de code :
Le morceau A de code est étroitement couplé au morceau B de code s'il existe une modification possible de la pièce B qui forcerait des changements dans la pièce A afin de conserver l'exactitude.
La pièce A de code n'est pas étroitement couplée à la pièce B de code s'il n'y a pas de modification possible de la pièce B qui rendrait nécessaire une modification de la pièce A.
Cela vous aidera à vérifier le degré de couplage entre les morceaux de votre code. pour raisonner à ce sujet, consultez ce billet de blog: http://marekdec.wordpress.com/2012/11/14/loose-coupling-tight-coupling-decoupling-what-is-that-all-about/
la source
Lorsque vous créez un objet d'une classe à l'aide de
new
mot-clé dans une autre classe, vous faites en fait un couplage serré (mauvaise pratique) à la place, vous devez utiliser un couplage lâche, ce qui est une bonne pratique--- A.java ---
--- B.java ---
--- InterfaceClass ---
--- MainClass ---
Explication:
Dans l'exemple ci-dessus, nous avons deux classes A et B
La classe B implémente Interface, c'est-à-dire InterfaceClass.
InterfaceClass définit un contrat pour la classe B car InterfaceClass a des méthodes abstraites de la classe B qui peuvent être accédées par n'importe quelle autre classe, par exemple A.
Dans la classe A, nous avons une méthode d'affichage qui peut exclure un objet de classe qui implémente InterfaceClass (dans notre cas, c'est la classe B). Et sur cet objet, la méthode de la classe A appelle display () et getVar () de la classe B
Dans MainClass, nous avons créé un objet de classe A et B. Et l'appel de la méthode d'affichage de A en passant un objet de classe B, c'est-à-dire objb. La méthode d'affichage de A sera appelée avec un objet de classe B.
Parlons maintenant de couplage lâche. Supposons qu'à l'avenir vous deviez changer le nom de la classe B en ABC, alors vous n'avez pas à changer son nom dans la méthode d'affichage de la classe B, faites simplement l'objet de new (classe ABC) et passez-le à la méthode d'affichage dans MailClass. Vous n'avez rien à changer dans la classe A
réf: http://p3lang.com/2013/06/loose-coupling-example-using-interface/
la source
Vous pouvez en savoir plus sur le concept générique de «couplage lâche» .
En bref, c'est une description d'une relation entre deux classes, où chaque classe en sait le moins sur l'autre et chaque classe pourrait potentiellement continuer à fonctionner très bien que l'autre soit présente ou non et sans dépendance sur l'implémentation particulière de l'autre classe.
la source
Le couplage lâche, en général, consiste en 2 acteurs travaillant indépendamment les uns des autres sur la même charge de travail. Donc, si vous aviez 2 serveurs Web utilisant la même base de données principale, vous diriez que ces serveurs Web sont faiblement couplés. Un couplage serré serait illustré par le fait d'avoir 2 processeurs sur un serveur Web ... ces processeurs sont étroitement couplés.
J'espère que c'est quelque peu utile.
la source