O padrão Observer usando o mecanismo pull

10

Eu estava pensando sobre a seguinte implementação de

public void update(Observable obs, Object arg)

enquanto eu quiser enviar para todo o meu observador e atualizar usando notifyObserver()I e passar uma referência ao thisobservador, pode usar o gettersdo assunto para obter as informações que ele deseja.

Para que serve o argargumento sobre o método de atualização?

USer22999299
fonte
@RBT argé um parâmetro ou grupo de parâmetros, como uma opção adicional
umlcat

Respostas:

11

Ao implementar o padrão Observer, há duas abordagens principais a serem consideradas: o modelo 'push' e o modelo 'pull'.

No modelo 'push', o sujeito (ou seja, o Observável) envia ao observador, mediante notificação, todos os dados necessários. O observador não precisa consultar o assunto para obter informações. No modelo 'pull', o sujeito apenas notifica o observador de que algo aconteceu, e o observador consulta o sujeito com base para obter as informações necessárias.

Vamos discutir os prós e contras de ambas as abordagens:

Empurrar

A principal vantagem do modelo "push" é o menor acoplamento entre o observador e o sujeito. O observador não precisa saber nada sobre o assunto para consultá-lo. Se necessário, precisamos fazer um dos seguintes: A- fazer downcasting do lado do observador para invocar getmétodos específicos de classe sobre o assunto. Isto é mau. B - tornar a Observableinterface mais específica da classe, oferecendo getmétodos específicos , tornando assim menos geral o relacionamento entre o observador e o sujeito e tornando as coisas mais copuplicadas.

Ao implementar o modelo "push", evitamos tudo isso.

No entanto, a desvantagem é menos flexibilidade: o sujeito nem sempre sabe quais informações exatas os observadores precisam para enviá-las a eles. Isso geralmente significa interfaces mais específicas do Observador, como as AgeObserverque são notificadas quando a 'idade' do sujeito é alterada e as HeightObserverquais são enviadas a corrente heightdo sujeito na notificação.

Esta é uma opção. O outro é o assunto que envia muitas informações encapsuladas em um Infoobjeto de algum tipo e solicita que os observadores as consultem a partir daí. Mais uma vez, não podemos ter certeza de que estamos enviando as informações corretas. Portanto, é isso ou forçar os observadores a implementar interfaces mais específicas do Observador, o que aperta o acoplamento do lado do observador.

Puxar

Eu já notei as desvantagens do modelo 'pull'. Os observadores precisariam saber coisas sobre o assunto para consultar as informações corretas, o que leva A a downcasting (feio), ou B- favoravelmente a Observableinterfaces mais específicas , que oferecem métodos de acesso mais específicos. Por exemplo, AgeObservableoferece um getAge()método

A vantagem disso é mais flexibilidade. Cada observador pode decidir por si próprio o que consultar, sem depender do assunto para enviar as informações corretas.


Você deve escolher a estratégia melhor para o projeto específico em que está trabalhando.

Na realidade, você sempre terá interfaces específicas Observere Observable, portanto, terá algum acoplamento entre os lados.

Portanto, escolha "puxar" ou "empurrar" de acordo com o que melhor lhe convier.

Todos os AgeObservers precisam simplesmente agedo assunto? Implemente o modelo 'push'. Menos acoplamento e mais simples.

Todos os HeightObservers precisam de informações variadas sobre o assunto - também é necessário consultar a idade, e algum outro objeto precisa consultar o peso além da altura? Implemente o modelo 'pull'. Isso forçaria você a adicionar acessadores (getters) à Observableinterface (isso ou passar o objeto real como um parâmetro em seu tipo explícito, mas fazer isso por meio da interface permite negar aos observadores o acesso a coisas que não importam eles). Essa alma cria maior acoplamento, mas é mais flexível.

Escolha o que melhor se adapta à sua situação.

Aviv Cohn
fonte
Obrigado por esta explicação. Voltando à minha pergunta, como você disse enquanto usava o pull, preciso baixar e usar os getters, mas qual é o argumento no método de atualização do observador? - atualização do vazio público (Obs Observable, Object arg)?
precisa saber é o seguinte
Não tenho certeza, mas acho que isso Object argse destina ao modelo 'push', onde argé enviado um 'pacote de informações' ao observador.
Aviv Cohn
Sim, isso é o que eu estava pensando também, mas então por que enviamos o obs? :) se lançarmos a base, podemos simplesmente puxar as informações de que precisamos.
precisa saber é o seguinte
1
Você está falando de 'empurrar' ou 'puxar'? A idéia em 'empurrar' é que o observador não precisa saber sobre o tipo de sujeito. Assim, você evita o down-casting. A redução de elenco é principalmente ruim, pois cria um acoplamento mais apertado entre os dois lados - o observador agora conhece o tipo exato de assunto, o que supera todo o propósito. E se mais tarde uma nova classe implementar a Observableinterface? Se você não confiar no tipo concreto do assunto - ou seja, ao não fazer a rejeição - o código atual do observador funcionará da mesma forma, polimorficamente, com o novo assunto.
Aviv Cohn
1
Se o código do observador se basear na baixa, ele precisará ser alterado a cada nova classe que implemente a interface Observable, derrotando assim todo o objetivo do padrão. Este é um exemplo de por que 'programar para uma interface, não uma implementação concreta' é uma coisa boa - o código que funciona contra uma interface funcionará inalterado a cada nova classe que implementa a interface. Se você confiar na implementação concreta - por exemplo, fazendo downcasting, seu código precisará ser alterado a cada nova classe Observable. Superando todo o propósito.
Aviv Cohn