[Modo] patrones de diseño Diseño cursos (cuatro) - modo de observador

escena

  • Observador / Acontecimiento, son modelo de "Colaboración de componentes" para resolver el problema del marco de colaboración y aplicación
  • La motivación: En el proceso de construcción de software, la necesidad de construir ciertos objetos de un "aviso - dependencias", es decir, el estado de un objeto (objeto de destino) se cambia, todos los objetos dependientes (objetos observador) serán notificados Si dicha dependencia demasiado de cerca, el software no será así para resistir el cambio
  • la tecnología orientada a objetos, esta dependencia puede debilitarse, Dependencia formar una estable, reduciendo el software del sistema de acoplamiento

Ejemplos

MainForm1.cpp

1  clase MainForm: pública Formulario
 2  {
 3      Cuadro de texto * txtFilePath;
4      TextBox * txtFileNumber;
5      ProgressBar * progressBar;
6  
7  pública :
 8      vacío Button1_Click () {
 9  
10          cuerdas rutaArchivo = txtFilePath-> getText ();
11          int número = atoi (txtFileNumber-> getText () c_str ().);
12  
13          FileSplitter divisor (filePath, número, progressBar);
14  
15          splitter.split ();
16  
17      }
 18 };
Ver código

FileSplitter1.cpp

1  clase FileSplitter
 2  {
 3      cadena m_filePath;
4      int m_fileNumber;
5      ProgressBar * m_progressBar;
6  
7  público :
 8      FileSplitter ( const  cadena y filePath, int FileNumber, ProgressBar * progressBar):
 9          m_filePath (filePath), 
 10          m_fileNumber (FileNumber),
 11          m_progressBar (progressBar) {
 12      }
 13  
14      void split () {
 15  
16         @ 1 leer los documentos
 17.  
18 es          // 2. Los lotes pequeños para escribir en el fichero de 
19.          Para ( int I = 0 ; I <m_fileNumber; I ++ ) {
 20 es              // ... 
21 es              un flotador progressValue = m_fileNumber;
 22 es              progressValue = (I + 1. ) / progressValue;
 23 es              m_progressBar-> el setValue (progressValue);
 24          }
 25  
26 es      }
 27 };
Ver código
  • programa divisor de archivo para archivos de gran tamaño, es necesario dividir la barra de progreso muestra el progreso
  • MainForm1 dos recogida de parámetros de entrada de usuario, se transmite a FIleSplitter1
  • Pregunta: violación de la Dependencia Inversión Principio. Realización (FileSplitter) se basan detalles (ProgressBar), y los detalles son susceptibles de cambio (por ejemplo, un interruptor tarde para Etiqueta muestran avances, o ninguna interfaz gráfica en la plataforma Linux, con ... representan el progreso)
  • Dependencia: se refiere al nivel de compilador-dependiente (A B dependiente, A tiempo de compilación necesarios para compilar B)
  • No confíe en los detalles, pero dependerá de lo abstracto
  • control ProgressBar es una notificación específica, está disponible de forma abstracta representación (Interfaz IProgress)

MainForm2.cpp

1  clase MainForm: público de forma, pública IProgress
 2  {
 3      Cuadro de texto * txtFilePath;
4      TextBox * txtFileNumber;
5  
6      ProgressBar * progressBar;
7  
8  pública :
 9      nula Button1_Click () {
 10  
11          cuerdas rutaArchivo = txtFilePath-> getText ();
12          int número = atoi (txtFileNumber-> getText () c_str ().);
13  
14          ConsoleNotifier CN;
15  
16         FileSplitter divisor (filePath, número);
17  
18          splitter.addIProgress ( este ); // 订阅通知
19          splitter.addIProgress (y cn); // 订阅通知
20  
21          splitter.split ();
22  
23          splitter.removeIProgress ( este );
24  
25      }
 26  
27      virtual  void DoProgress ( float valor) {
 28          progressBar-> setValue (valor);
29      }
 30  };
31  
32  claseConsoleNotifier: público IProgress {
 33  pública :
 34      virtual  void DoProgress ( float valor) {
 35          cout << " " ;
36     }
 37 }; 
Ver código

FileSplitter2.cpp

. 1  clase IProgress {
 2  pública :
 . 3      virtual  void DoProgress ( un flotador valor) = 0 ;
 . 4      Virtual ~ IProgress () {}
 . 5  };
 . 6  
. 7  clase FileSplitter
 . 8  {
 . 9      Cadena m_filePath;
 10      int m_fileNumber;
 . 11  
12 es      List <IProgress *> m_iprogressList; // mecanismo de notificación abstracto para soportar una pluralidad de observadores 
13 es      
14  pública :
 15      FileSplitter ( const  cadenaFilePath y, int FileNumber):
 16          m_filePath (filePath), 
 . 17          m_fileNumber (FileNumber) {
 18 es  
19.      }
 20 es  
21 es      void split () {
 22 es  
23 es          // 1. archivo grande leer
 24  
25          @ 2 a pequeños lotes archivo de escritura 
26 es          de ( int I = 0 ; I <m_fileNumber; I ++ ) {
 27              // ... 
28  
29              un flotador progressValue = m_fileNumber;
 30              progressValue = (I + . 1 ) /pro gre ssValue;
31              onProgress (pro gre ssValue); // 发送通知
32          }
 33  
34      }
 35  
36  
37      vacío addIProgress (* Progreso Progreso) {
 38          m_iprogressList.push_back (PROGRESS);
39      }
 40  
41      void removeIProgress (* Progreso Progreso) {
 42          m_i pro gre Asli st.remove (PROGRESS);
43      }
 44  
45  protegida :
 46      virtual  void onProgress ( float valor) {
47          
48          Lista <IProgress *> :: = iterador itor m_iprogressList.begin ();
49  
50          , mientras que (itor =! M_iprogressList.end ())
 51              (* itor) -> DoProgress (valor); // 更新进度条
52              Itor ++ ;
53          }
 54      }
 55 };
Ver código
  • Adición de una clase base abstracta IProgress, a partir de la notificación original del control en una notificación específica mecanismo abstracto
  • Generalmente no se recomienda C ++ admite la herencia múltiple, pero puede conducir a problemas de acoplamiento,
  • Sólo en un caso con la recomendación, es decir, la clase derivada de la clase padre es un primario (Form1), o otras interfaces son de clase base abstracta (IProgress)
  • Después de la reconstitución, las clases FileSplitter ya no están acoplados interfaz de clases (la ProgressBar), para lograr una compilación separada, en línea con la Dependencia Inversion Principio
  • El futuro puede ser colocado en la interfaz de Windows, Linux o ejecutar la interfaz, la función de notificación de horarios dependen de la finalización de IProgress abstracta
  • Formalmente, DoProgress () de la línea FileSplitter1.cpp 23, y se trasladó a la línea 28 MainForm2.cpp
  • Utilizando el contenedor, que soporta una pluralidad de observadores (línea de comandos, la interfaz gráfica de usuario, etc.), la escritura FileSplitter constructor de la clase se cambia
  • proceso de reconstrucción
    • ProgressBar * m_progressBar; // Controles aviso específico
    • IProgress * m_iprogress; // mecanismo de notificación abstracta
    • List <IProgress *> m_iprogressList; // Ayuda múltiples observadores

resumen

  • Diagrama de clases, Observador equivalente IProgress, Actualización corresponde DoProgress (), Asunto y ConcreteSubject FileSplitter equivalente, Adjuntar () correspondiente a addIProgress (), Notify () correspondiente a onProgress (), ConcreteObserver MainForm equivalente y ConsoleNotifier
  • Asunto y Observador son estables, ConcreteSubject y ConcreteObserver están cambiando
  • patrón Observer de manera que podemos cambiar independientemente la diana y el observador, de modo que la relación de dependencia entre los dos está acoplado libremente
  • Cuando el destino envía una notificación sin especificar el espectador, la notificación se propagará de forma automática (no se sabe quién es el observador)
  • El espectador decidir si para suscribirse a notificaciones, el público no sabía nada de
  • marco UI modelo Observador se basa en el caso de un patrón muy común, es una parte importante del patrón MVC

Supongo que te gusta

Origin www.cnblogs.com/cxc1357/p/12288002.html
Recomendado
Clasificación