O padrão Observer no Delphi estende o padrão Observer básico. Para obter mais informações sobre o modo Observador, consulte [Gam+, páginas 293..303]
Defina um relacionamento de dependência um-para-muitos entre objetos Quando o estado de um objeto muda, todos os objetos que dependem dele são notificados e atualizados automaticamente.
A divisão de um sistema em uma série de classes cooperantes tem certos efeitos colaterais: a consistência entre objetos relacionados deve ser protegida. Não queremos acoplar tipos firmemente por uma questão de consistência dimensional, porque isso reduz sua reutilização. [Gam+,p293].
Os eventos do Delphi (endereços reais dos métodos) permitem que você tenha uma boa estrutura para lidar com esses problemas. Os eventos permitem eliminar o acoplamento e obter um melhor acoplamento. Por exemplo: o evento TButton.OnClick é despachado para concluir o trabalho relacionado. Mas a classe não salva uma referência ao manipulador de eventos. No padrão observador, a classe que despacha o evento é chamada de objeto alvo (sujeito), e a classe que controla o evento é chamada de observador (observador).
Os eventos no Delphi podem eliminar melhor o acoplamento de classes. Se você deseja controlar vários eventos e consultar o modo observador, pode estabelecer um mecanismo de notificação um para muitos. Um alvo pode ter qualquer número de observadores. Todos os observadores recebem notificações quando o estado do alvo muda. Depois que o observador recebe a notificação, ele consulta imediatamente o objeto de destino para manter a sincronização com o objeto de destino.
Essa interação também é chamada de publicação-assinatura e o alvo é o publicador da notificação. Ele não precisa saber quem são seus observadores quando descobre uma notificação. Qualquer número de observadores pode se inscrever e receber notificações.
Este aplicativo em modo observador trará a você as vantagens do mecanismo de eventos Delphi no tratamento do acoplamento de classes. Estruturas um-para-muitos registram observadores por meio de registro e cancelamento de registro. O mecanismo um-para-muitos é, na verdade, aplicado com base em iteradores.
Suponha que você tenha uma classe Tsubject que defina um comportamento significativo. Vejamos primeiro um código de demonstração do modo observador:
tipo
TSubject = classe (TObject)
Privado
FObservidores: TList;
público
procedimento RegisterObserver(Observador: TSubjectObserver);
procedimento UnregisterObserver(Observador: TSubjectObserver);
fim;
TSubjectObserver = classe (TComponent)
privado
FEnabled: Booleano;
publicado
propriedade Enabled: Boolean read FEnabled write FEnabled padrão True;
fim;
Entre as interfaces acima:
? Um mecanismo de registro para registrar observadores no Tsubject.
¨ FObservers: TList; armazena observadores registrados.
¨ RegisterObserver(..) é usado para registrar observadores e adicioná-los aos Fobservers.
¨ UnregisterObserver(..) é usado para cancelar o registro do observador e remover objetos relacionados dos Fobservers.
?O modo observador também precisa criar uma nova classe TsubjectObserver
¨ Esta classe é descendente de Tcomponent.
¨ .Uma propriedade Enabled ativa ou desativa a observação. .
A aplicação real do seguinte modo de observador:
procedimento TSubject.RegisterObserver(Observador: TSubjectObserver);
começar
se FObservers.IndexOf(Observer) = -1 então
FObservers.Add(Observador);
fim;
procedimento TSubject.UnregisterObserver(Observador: TSubjectObserver);
começar
FObservers.Remove(Observador);
fim;
A implementação do Shangguan apoia a parte de registro dos observadores. Onde está o mecanismo de notificação um para muitos? Para aplicativos de notificação um-para-muitos reais, você pode definir um método Change para Tsubject notificar seus observadores registrados, e o observador pode definir um atributo de evento OnChange para lidar com o agendamento. O código é o seguinte:
tipo
TSubject = classe (TObject)
privado
FObservidores: TList;
protegido
» Alteração de procedimento; {Chame este método para despachar notificação}
público
procedimento RegisterObserver(Observador: TSubjectObserver);
procedimento UnregisterObserver(Observador: TSubjectObserver);
fim;
TSubjectObserver = classe (TComponent)
privado
FEnabled: Booleano;
» FOnChange: TNotifyEvent;
protegido
» Alteração de Procedimento;
publicado
propriedade Enabled: Boolean read FEnabled write FEnabled;
» propriedade OnChange: TNotifyEvent lê FOnChange escreve FOnChange;
fim;
implementação
procedimentoTSubject.Change;
var
» Obs: TSubjectObserver;
» I: Inteiro;
começar
» para I := 0 para FObservers.Count - 1 do
" começar
» Obs := FObservers[I];
» se Obs.Enabled então Obs.Change;
" fim;
fim;
procedimento TSubject.RegisterObserver(Observador: TSubjectObserver);
começar
se FObservers.IndexOf(Observer) = -1 então
FObservers.Add(Observador);
fim;
procedimento TSubject.UnregisterObserver(Observador: TSubjectObserver);
começar
FObservers.Remove(Observador);
fim;
procedimentoTSubjectObserver.Change;
começar
» se Atribuído(FOnChange) então FOnChange(Self);
fim;
No código de implementação acima:
? O método Change de Tsubject percorre todos os observadores registrados e chama o método Change de cada observador, uma implementação de uma notificação um-para-muitos.
? A propriedade Enabled do observador determina se ele é ou recebe notificações
? O evento OnChange do TsubjectObserver realmente lida com sincronização e outras operações.
Organizando
//Muitos trechos de "Design Patterns"