El patrón Observer en Delphi extiende el patrón Observer básico. Para obtener más información sobre el modo Observador, consulte [Gam+, páginas 293..303]
Defina una relación de dependencia de uno a muchos entre objetos. Cuando el estado de un objeto cambia, todos los objetos que dependen de él son notificados y actualizados automáticamente.
Dividir un sistema en una serie de clases cooperativas tiene ciertos efectos secundarios: se debe proteger la coherencia entre objetos relacionados. No queremos acoplar tipos estrechamente por razones de consistencia dimensional, porque esto reduce su reutilización. [Gam+,p293].
Los eventos de Delphi (direcciones de métodos reales) le permiten tener una buena estructura para manejar estos problemas. Los eventos le permiten eliminar el acoplamiento y lograr un mejor acoplamiento. Por ejemplo: el evento TButton.OnClick se envía para completar el trabajo relacionado. Pero la clase no guarda una referencia al controlador de eventos. En el patrón de observador, la clase que envía el evento se llama objeto objetivo (sujeto) y la clase que controla el evento se llama observador (observador).
Los eventos en Delphi pueden eliminar mejor el acoplamiento de clases. Si desea controlar múltiples eventos y hacer referencia al modo observador, puede establecer un mecanismo de notificación de uno a muchos. Un objetivo puede tener cualquier número de observadores. Todos los observadores reciben notificaciones cuando cambia el estado del objetivo. Después de que el observador recibe la notificación, consulta inmediatamente al objeto de destino para mantener la sincronización con el objeto de destino.
Esta interacción también se denomina publicación-suscripción y el objetivo es el editor de la notificación. No necesita saber quiénes son sus observadores cuando descubre una notificación. Cualquier número de observadores puede suscribirse y recibir notificaciones.
Esta aplicación en modo observador le brindará las ventajas del mecanismo de eventos de Delphi en el manejo del acoplamiento de clases. Las estructuras uno a muchos registran a los observadores mediante el registro y la cancelación del registro. El mecanismo de uno a muchos en realidad se aplica sobre la base de iteradores.
Supongamos que tiene una clase Tsubject que define un comportamiento significativo. Primero veamos un código de demostración del modo observador:
tipo
TSubject = clase (TObject)
Privado
FObservadores: TList;
público
procedimiento RegisterObserver (Observador: TSubjectObserver);
procedimiento UnregisterObserver(Observador: TSubjectObserver);
fin;
TSubjectObserver = clase (TComponent)
privado
FEnabled: booleano;
publicado
propiedad habilitada: lectura booleana FEnabled escritura FEnabled; valor predeterminado Verdadero;
fin;
Entre las interfaces anteriores:
? Un mecanismo de registro para registrar observadores para Tsubject.
¨ FObservers: TList almacena observadores registrados.
¨ RegisterObserver(..) se utiliza para registrar observadores y agregarlos a Fobservers.
¨ UnregisterObserver(..) se utiliza para cancelar el registro del observador y eliminar objetos relacionados de Fobservers.
?El modo observador también necesita crear una nueva clase TsubjectObserver
¨ Esta clase es descendiente de Tcomponent.
¨ .Una propiedad Habilitada activa o desactiva la observación. .
La aplicación real del siguiente modo de observador:
procedimiento TSubject.RegisterObserver (Observador: TSubjectObserver);
comenzar
si FObservers.IndexOf(Observer) = -1 entonces
FObservers.Add(Observador);
fin;
procedimiento TSubject.UnregisterObserver (Observador: TSubjectObserver);
comenzar
FObservers.Remove(Observador);
fin;
La implementación de Shangguan apoya la parte de registro de observadores. ¿Dónde está el mecanismo de notificación uno a muchos? Para aplicaciones reales de notificación de uno a muchos, puede definir un método de cambio para que Tsubject notifique a sus observadores registrados, y el observador puede definir un atributo de evento OnChange para manejar la programación. El código es el siguiente:
tipo
TSubject = clase (TObject)
privado
FObservadores: TList;
protegido
» Cambio de procedimiento; {Llame a este método para enviar la notificación}
público
procedimiento RegisterObserver (Observador: TSubjectObserver);
procedimiento UnregisterObserver(Observador: TSubjectObserver);
fin;
TSubjectObserver = clase (TComponent)
privado
FEnabled: booleano;
» FOnChange: TNotifyEvent;
protegido
» Cambio de Procedimiento;
publicado
propiedad habilitada: lectura booleana FEnabled escritura FEnabled;
» propiedad OnChange: TNotifyEvent lee FOnChange escribe FOnChange;
fin;
implementación
procedimientoTSubject.Change;
var
»Obs: TSubjectObserver;
» I: Entero;
comenzar
» para I := 0 a FObservers.Count - 1 hacer
" comenzar
» Obs := FObservadores[I];
» si Obs.Enabled entonces Obs.Change;
" fin;
fin;
procedimiento TSubject.RegisterObserver (Observador: TSubjectObserver);
comenzar
si FObservers.IndexOf(Observer) = -1 entonces
FObservers.Add(Observador);
fin;
procedimiento TSubject.UnregisterObserver (Observador: TSubjectObserver);
comenzar
FObservers.Remove(Observador);
fin;
procedimientoTSubjectObserver.Change;
comenzar
» si está asignado (FOnChange) entonces FOnChange (Self);
fin;
En el código de implementación anterior:
? El método Change de Tsubject itera a través de todos los observadores registrados y llama al método Change de cada observador, una implementación de una notificación de uno a muchos.
? La propiedad Enabled del observador determina si recibe o recibe notificaciones.
? El evento OnChange de TsubjectObserver en realidad maneja la sincronización y otras operaciones.
organizando
//Muchos extractos de "Patrones de diseño"