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 get
métodos específicos de classe sobre o assunto. Isto é mau. B - tornar a Observable
interface mais específica da classe, oferecendo get
mé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 AgeObserver
que são notificadas quando a 'idade' do sujeito é alterada e as HeightObserver
quais são enviadas a corrente height
do sujeito na notificação.
Esta é uma opção. O outro é o assunto que envia muitas informações encapsuladas em um Info
objeto 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 Observable
interfaces mais específicas , que oferecem métodos de acesso mais específicos. Por exemplo, AgeObservable
oferece 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 Observer
e Observable
, portanto, terá algum acoplamento entre os lados.
Portanto, escolha "puxar" ou "empurrar" de acordo com o que melhor lhe convier.
Todos os AgeObserver
s precisam simplesmente age
do assunto? Implemente o modelo 'push'. Menos acoplamento e mais simples.
Todos os HeightObserver
s 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) à Observable
interface (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.
arg
é um parâmetro ou grupo de parâmetros, como uma opção adicional