Définition: encapsuler une série d'interactions d'objets avec un objet médiateur. Le médiateur fait que chaque objet interagit sans affichage, desservant ainsi le couplage et changeant indépendamment de l'interaction entre eux.
Type: Diagramme de classe de modèle de classe de comportement:
La structure du modèle intermédiaire
Le mode intermédiaire est également appelé mode médiateur. Du diagramme de classe, il est divisé en 3 parties:
Résumé Médiateur: définissez l'interface entre les objets de classe de collègues et les objets médiateurs, et est utilisé pour la communication entre chaque classe de collègues. Généralement, il comprend une ou plusieurs méthodes d'événements abstraites et est implémentée par des sous-classes.
Classe de mise en œuvre intermédiaire: Hérité des médiateurs abstraits et met en œuvre des méthodes d'événements définies dans les médiateurs abstraits. Recevez des messages d'une classe de collègues, puis influentez d'autres classes simultanées via le message.
Classe de collègues: Si un objet affecte d'autres objets et est également affecté par d'autres objets, ces deux objets sont appelés classes de collègues. Dans le diagramme des classes, il n'y a qu'une seule classe de collègues, qui est en fait une omission de réalité. Dans les applications pratiques, la classe de collègues est généralement composée de multiples, et ils influencent et dépendent les uns des autres. Plus il y a de collègues, plus les relations sont compliquées. De plus, la classe de collègues peut également être représentée comme un ensemble d'implémentations héritant de la même classe abstraite. Dans le modèle intermédiaire, le message doit être transmis par des intermédiaires entre collègues.
Pourquoi utiliser le modèle intermédiaire
D'une manière générale, la relation entre les classes de collègues est relativement complexe. Lorsque plusieurs classes de collègues sont corrélées, leur relation apparaîtra comme une structure de maillage complexe. Il s'agit d'une architecture trop couplée, c'est-à-dire qu'elle n'est pas propice à la réutilisation de classe et n'est pas stable. Par exemple, dans la figure ci-dessous, il y a six objets de type collègue. Si l'objet 1 change, 4 objets seront affectés. Si l'objet 2 change, alors 5 objets seront affectés. En d'autres termes, la conception de la corrélation directe entre ses collègues n'est pas bonne.
Si le modèle intermédiaire est introduit, la relation entre les classes de collègues deviendra une structure star. D'après la figure, nous pouvons voir que les changements dans n'importe quelle classe ne affecteront que la classe elle-même et l'intermédiaire, ce qui réduira le couplage du système. Une bonne conception ne résumera certainement pas à toutes les logiques de traitement de l'objet-relation dans cette classe, mais utilisera une classe spéciale pour gérer les comportements qui ne vous appartiennent pas.
exemple
Voici un exemple de code spécifique. Par rapport au diagramme de classe générale, la classe de collègues abstraite de la Colléable et le médiateur abstrait abstrait sont ajoutés. De plus, il existe deux classes de collègues spécifiques et un médiateur spécifique. Il existe de nombreux commentaires dans le code, et le diagramme de classe correspondant n'est pas donné, ce qui ne devrait pas être difficile à comprendre:
Collègues:
// classe de collègues abstrait classe abstraite abstractcolleague {médiateur abstraitmètre protégé; / ** Puisqu'il y a un intermédiaire, chaque collègue spécifique doit avoir un contact avec l'intermédiaire, * sinon, il n'est pas nécessaire d'exister dans ce système. Le constructeur ici équivaut à enregistrer un intermédiaire avec le système pour contacter * / public abstractcolleague (AbstractMediator Mediateur) {this.mediator = médiateur; } // Ajouter une méthode pour contacter l'intermédiaire (c'est-à-dire l'enregistrement) dans la classe de collègue abstraite publique void setMediator (médiateur abstractmediator) {this.mediator = médiateur; }} // collègue spécifique Une classe Collègue étend Abstractcolleague {// chaque collègue spécifique contacte le médiateur par le biais de la classe de la classe Public Colleaguea (médiateur abstractMediateur) {super (médiateur); } // Chaque collègue spécifique doit avoir ses propres tâches, et il n'est pas nécessaire d'être associé au monde extérieur public void self () {System.out.println ("Colleaguea -> faire vos propres tâches ..."); } // Chaque collègue spécifique a toujours besoin d'interagir avec le monde extérieur, de gérer ces logiques et d'organiser le travail via le médiateur public void out () {System.out.println ("collègue -> Demande de collègue B pour faire son travail à temps partiel ..."); super.Mediator.Execute ("Collègue", "self"); }} // Collègue spécifique B CLASEAGEB Étend Abstractcolleague {public CollegeB (AbstractMediator Mediator) {Super (médiateur); } public void self () {System.out.println ("collègue b -> faire votre travail à temps partiel ..."); } public void out () {System.out.println ("Collègue B -> Demande de collègue A pour faire son travail à temps partiel ..."); super.Mediator.Execute ("Colleaguea", "self"); }} Catégorie intermédiaire:
// Résumé Intermediaire Résumé Classe AbstractMediator {// L'intermédiaire doit maintenir les informations de contact de plusieurs collègues protégés HashTable <String, Abstractcolleague> collègues = nouveau hashtable <String, AbstractcolleAGE> (); // L'intermédiaire peut établir dynamiquement le contact avec un collègue public void addcolleague (nom de chaîne, abstractcolleague c) {this.colleagues.put (nom, c); } // L'intermédiaire peut également annuler dynamiquement le contact avec un collègue public void DeleteCoLeague (nom de chaîne) {this.colleagues.remove (name); } // L'intermédiaire doit avoir des opérations pour gérer la logique, attribuer des tâches et promouvoir la communication entre ses collègues } // Classe intermédiaire spécifique Mediator étend AbstractMediator {// La fonction la plus importante de l'intermédiaire est de faire des allers (Collègue) super.collegues.get ("collègue"); collègue.self (); } else {collègueb collègue = (collègueb) super.collegues.get ("collègueb"); collègue.self (); }} else {// College avec d'autres collègues if ("collègue" .equals (name)) {collègue collègue = (colleaguea) super.collegues.get ("collègue"); collègue.out (); } else {collègueb collègue = (collègueb) super.collegues.get ("collègueb"); collègue.out (); }}}}} Classe de test:
// CLASSE DE TEST CLASSE PUBLIC CLIENT {public static void main (String [] args) {// Créer un médiateur abstractmediator intermédiaire = new Mediateur (); // Créer deux collègues collègues collègues = New Colleaguea (médiateur); Collègueb collègueb = nouveau collègueb (médiateur); // l'intermédiaire établit des contacts avec chaque collègue médiateur.addcolleague ("collègue", collègue); Mediator.adddcolleague ("ColleagueB", ColleagueB); // collègues commencent à travailler colleague.self (); colleaguea.out (); System.out.println("========================================================================================================= =======================================================================. ========================================================================. =======================================================================. ========================================================================. ========================================================================. ========================================================================. Résultats des tests:
Colleague A --> Do your part in your duties... Colleague A --> Ask Colleague B to do your part in your duties... Colleague B --> Do your part in your duties... ================================================= Happy cooperation, the task is completed! Colleague B --> Do your part in your duties... Colleague B --> Ask Colleague A to do your part in your duties... Colleague A --> Do your part in your duties... =================================================== Happy cooperation, the task is completed!
Bien qu'il n'y ait que deux classes de collègues spécifiques dans le code ci-dessus, et que seulement deux collègues sont créés dans la classe de test, nous pouvons les élargir de manière appropriée en fonction de l'objectif du modèle intermédiaire, c'est-à-dire ajouter des classes de collègues spécifiques, puis l'intermédiaire doit assumer des tâches plus lourdes. Pourquoi? Nous voyons qu'il y a maintenant un tas de codes de jugement long dans la méthode EXECUTE () dans la classe de médiateur ci-dessus. Bien qu'il puisse être décomposé et ajouté à d'autres méthodes privées de la classe de médiateurs, une logique métier spécifique est indispensable.
Par conséquent, tout en découplant le lien entre collègues, l'intermédiaire lui-même est également incompatible avec les tâches exagérées, car presque toute la logique commerciale est expliquée à l'intermédiaire, qui peut être décrite comme un rôle "très attendu". Ce sont les lacunes du modèle intermédiaire.
De plus, l'exemple de code ci-dessus est assez idéal. Parfois, nous ne pouvons pas extraire les points communs entre les «collègues» pour former une classe de collègues abstraites abstraits, ce qui augmente considérablement la difficulté d'utiliser le modèle intermédiaire.
Réviser:
Puisqu'il y a des lacunes dans la mise en œuvre du code ci-dessus de "l'association bidirectionnelle exposée dans l'application" proposée par le senior Benjielin, selon la méthode d'amélioration donnée 2, modifiez le code ci-dessus comme suit:
Collègues modifiés:
// classe abstraite AbstractColleague {médiateur abstraittMediator protégé; // Arrête d'établir une connexion avec le médiateur dans le constructeur // public abstractcolleague (médiateur abstractMediator) {// this.mediator = médiateur; //} // ajouter une méthode à la classe de collègues abstraite pour contacter le médiateur (c'est-à-dire l'enregistrement) public void setMediator (médiateur abstraitmediateur) {this.mediator = médiateur; }} // collègue spécifique Une classe Collègue étend Abstractcolleague {// n'établissez pas de connexion avec le médiateur dans le constructeur // Public Collegea (médiateur abstractmediateur) {// super (médiateur); //} // Chaque collègue spécifique doit avoir sa propre partie de sa propre partie, et il n'est pas nécessaire d'être associé au monde extérieur public Void Self () {System.out.println ("Colleaguea -> Faites votre partie de sa part ..."); } // Chaque collègue spécifique a toujours besoin d'interagir avec le monde extérieur, de gérer ces logiques et d'organiser le travail par le biais du médiateur public void out () {System.out.println ("Colleaguea -> Demande de collègue B pour faire la partie de sa partie de sa partie ..."); super.Mediator.Execute ("Collègue", "self"); }} // collègue spécifique de classe B Collègueb étend Abstractcolleague {// Arrête d'établir une connexion avec le médiateur dans le constructeur // Collègue public (médiateur abstractMediator) {// super (médiateur); //} public void self () {System.out.println ("collègueb -> faire votre part ..."); } public void out () {System.out.println ("collègueb -> Demandez au collègue A de faire votre part ..."); super.Mediator.Execute ("Colleaguea", "self"); }}
Intermédiaire modifié:
// Résumé Intermediaire Résumé Classe AbstractMediator {// L'intermédiaire doit maintenir les informations de contact de plusieurs collègues protégés HashTable <String, Abstractcolleague> collègues = nouveau hashtable <String, AbstractcolleAGE> (); // L'intermédiaire peut établir dynamiquement le contact avec un collègue public void addcolleague (nom de chaîne, abstractcolleague c) {// aide ses collègues spécifiques à établir des contacts de l'intermédiaire C.SetMediator (this); this.colleages.put (nom, c); } // L'intermédiaire peut également révoquer dynamiquement le contact avec un collègue public void DeleteCoLeague (nom de chaîne) {this.colleagues.remove (name); } // L'intermédiaire doit avoir des opérations pour gérer la logique, attribuer des tâches et promouvoir la communication entre ses collègues } // La classe de test Client de classe publique {public static void main (String [] args) {// Créer un intermédiaire abstractMediator Mediator = new Mediator (); // Le constructeur est utilisé pour enregistrer l'intermédiaire pour des collègues spécifiques pour contacter // collègues colleaguea = new colleaguea (médiateur); // collègueb collègueb = nouveau collègueb (médiateur); Collègues colleaguea = new Colleaguea (); Collègueb collègueB = new colleagueB (); // l'intermédiaire établit des contacts avec chaque collègue médiateur.addcolleague ("collègue", collègue); Mediator.adddcolleague ("ColleagueB", ColleagueB); // Les collègues commencent à travailler collègue.self (); colleaguea.out (); System.out.println ("========================================================= ============================================================================. ============================================================================. ===============================================================================. ============================================================================. ============================================================================. ============================================================================. ===============================================================================.Les résultats après le test sont les mêmes qu'avant la modification.