[Design Mode] Cours de design patterns (quatre) - mode observateur

scène

  • Observer / événement, sont le modèle « Collaboration composants » pour résoudre le problème du cadre de collaboration et de l'application
  • Motivation: Dans le processus de construction de logiciels, la nécessité de construire certains objets d'un « avis - dépendances », à savoir l'état d'un objet (objet cible) est modifié, tous les objets dépendants (objets observateur) seront notifiés Si une telle dépendance trop étroite, le logiciel ne sera pas bien à résister au changement
  • la technologie orientée objet, cette dépendance peut être affaiblie, la dépendance former un stable, ce qui réduit le logiciel du système d'accouplement

Exemples

MainForm1.cpp

1  classe MainForm: publique Formulaire
 2  {
 3      TextBox * txtFilePath;
4      TextBox * txtFileNumber;
5      ProgressBar * progressBar;
6  
7  publique :
 8      vide Button1_Click () {
 9  
10          chaîne filePath = txtFilePath-> getText ();
11          int nombre = atoi (txtFileNumber-> getText () c_str ().);
12  
13          séparateur FileSplitter (filePath, nombre, progressBar);
14  
15          splitter.split ();
16  
17      }
 18 };
Afficher le code

FileSplitter1.cpp

Une  classe FileSplitter
 2  {
 3      chaîne m_filePath;
4      int m_fileNumber;
5      ProgressBar * m_progressBar;
6  
7  publique :
 8      FileSplitter ( const  string & filePath, int FileNumber, ProgressBar * progressBar):
 9          m_filePath (filePath), 
 10          m_fileNumber (FileNumber),
 11          m_progressBar (progressBar) {
 12      }
 13  
14      vide split () {
 15  
16         @ 1 lire les documents
 17.  
18 est          // 2. petits lots pour écrire dans le fichier 
19.          Pour ( int I = 0 ; I <m_fileNumber; I ++ ) {
 20 est              // ... 
21 est              un flotteur progressValue = m_fileNumber;
 22 est              progressValue = (I + 1. ) / progressValue;
 23 est              m_progressBar-> la setValue (progressValue);
 24          }
 25  
26 est      }
 27 };
Afficher le code
  • programme de séparateur de fichier pour les gros fichiers, nous avons besoin de partager la barre de progression affiche la progression
  • MainForm1 deux collecte de paramètres d'entrée d'utilisateur, est transmise à FIleSplitter1
  • Question: violation du principe d'inversion de dépendance. Réalisation (FileSplitter) se servent de détails (ProgressBar), et les détails sont susceptibles de changer (par exemple, un interrupteur fin au progrès show Label ou pas d'interface graphique dans la plate-forme Linux, avec ... représentent des progrès)
  • Dépendance: fait référence au niveau d'dépendant du compilateur (A B dépendante, une compilation nécessaire pour compiler B)
  • Ne comptez pas sur les détails, mais dépendre abstrait
  • contrôle ProgressBar est une notification spécifique, est disponible de manière abstraite (Interface IProgress) Représentation

MainForm2.cpp

1  classe MainForm: publique forme, publique IProgress
 2  {
 3      TextBox * txtFilePath;
4      TextBox * txtFileNumber;
5  
6      ProgressBar * progressBar;
7  
8  publique :
 9      vide Button1_Click () {
 10  
11          chaîne filePath = txtFilePath-> getText ();
12          int nombre = atoi (txtFileNumber-> getText () c_str ().);
13  
14          ConsoleNotifier cn;
15  
16         Répartiteur FileSplitter (filePath, nombre);
17  
18          splitter.addIProgress ( ce ); // 订阅通知
19          splitter.addIProgress (& cn); // 订阅通知
20  
21          splitter.split ();
22  
23          splitter.removeIProgress ( ce );
24  
25      }
 26  
27      virtuel  vide DoProgress ( float valeur) {
 28          progressBar-> setValue (valeur);
29      }
 30  };
31  
32  classeConsoleNotifier: publique IProgress {
 33  publique :
 34      virtuelle  vide DoProgress ( float valeur) {
 35          Cout << " " ;
36     }
 37 }; 
Afficher le code

FileSplitter2.cpp

. 1  classe IProgress {
 2  publique :
 . 3      Virtual  vide DoProgress ( un flotteur value) = 0 ;
 . 4      Virtual ~ IProgress () {}
 . 5  };
 . 6  
. 7  classe FileSplitter
 . 8  {
 . 9      cordes m_filePath;
 10      int m_fileNumber;
 . 11  
12 est      List <IProgress *> m_iprogressList; // mécanisme de notification abstraite pour supporter une pluralité d'observateurs 
13 est      
14  publique :
 15      FileSplitter ( const  cordesFilePath &, int filenumber):
 16          m_filePath (filePath), 
 . 17          m_fileNumber (filenumber) {
 18 est  
19.      }
 20 est  
21 est      vide de Split () {
 22 est  
23 est          // 1. grand fichier lu
 24  
25          @ 2 petits lots l' écriture du fichier 
26 est          pour ( int I = 0 ; I <m_fileNumber; I ++ ) {
 27              // ... 
28  
29              un flotteur progressValue = m_fileNumber;
 30              progressValue = (I + . 1 ) /pro gre ssValue;
31              onProgress (pro gre ssValue); // 发送通知
32          }
 33  
34      }
 35  
36  
37      vide addIProgress (* Progress Progress) {
 38          m_iprogressList.push_back (PROGRESS);
39      }
 40  
41      vide removeIProgress (* Progress {Progress)
 42          m_i pro gre Asli st.remove (PROGRESS);
43      }
 44  
45  protégé :
 46      virtuel  vide onProgress ( float valeur) {
47          
48          Liste <IProgress *> :: iterator = Itor m_iprogressList.begin ();
49  
50          tandis que (Itor =! M_iprogressList.end ())
 51              (* Itor) -> DoProgress (valeur); // 更新进度条
52              Itor ++ ;
53          }
 54      }
 55 };
Afficher le code
  • Ajout d'une classe de base abstraite IProgress, à partir de la notification initiale de contrôle dans un mécanisme de notification spécifique abstraite
  • c ++ supports d'héritage multiple, mais peut conduire à des problèmes de couplage, est généralement pas recommandé
  • Dans un seul cas avec la recommandation, à savoir la classe dérivée classe parent est un primaire (Form1), ou d'autres interfaces sont classe de base abstraite (IProgress)
  • Après reconstitution, les classes FileSplitter ne sont plus couplés l'interface des classes (la barre de progression), pour obtenir une compilation séparée, conformément à la inversion des dépendances
  • L'avenir peut être placé dans l'interface Windows ou Linux d'exécuter l'interface, la fonction de notification de programme dépend de la réalisation des résumés IProgress
  • Formellement, DoProgress () à partir de la ligne FileSplitter1.cpp 23, et déplacé à la ligne 28 MainForm2.cpp
  • En utilisant le récipient, supportant une pluralité d'observateurs (ligne de commande, l'interface graphique, etc.), l'écriture constructeur de la classe FileSplitter est modifiée
  • processus de reconstruction
    • ProgressBar * m_progressBar // Controls Avis spécifique
    • IProgress * m_iprogress; // mécanisme abstrait de notification
    • Liste <IProgress *> m_iprogressList; // soutien de plusieurs observateurs

résumé

  • Diagramme de classes, Observateur équivalent IProgress, mise à jour correspond DoProgress (), Objet et ConcreteSubject FileSplitter équivalent, attach () correspondant à addIProgress (), notify () correspondant à onProgress (), ConcreteObserver équivalent MainForm et ConsoleNotifier
  • Objet et observateur sont stables, ConcreteSubject et ConcreteObserver changent
  • modèle Observateur de sorte que l'on peut changer indépendamment la cible et l'observateur, de sorte que la relation de dépendance entre les deux est couplé de manière lâche
  • Lorsque la cible envoie une notification sans spécifier le spectateur, la notification se propage automatiquement (ne sait pas qui l'observateur)
  • Le spectateur de décider de souscrire aux notifications, le public ne savait rien
  • modèle d'observateur est basé cadre de l'interface utilisateur dans le cas où un modèle très courant, est une partie importante du modèle MVC

Je suppose que tu aimes

Origine www.cnblogs.com/cxc1357/p/12288002.html
conseillé
Classement