O padrão de desenho mais correcto a aplicar neste caso é o Observer. A entidade ConcreteSubject deste padrão corresponderá à entidade Emprestimo do exemplo de aplicação. A entidade Subject fornece a funcionalidade genérica de notificar todas entidades interessadas sempre que o subject é alterada:
public class Subject { private List<Observer> observers = new ArrayList<Observer>(); public void registerObserver(Observer observer) { observers.add(observer); } public void removeObserver(Observer observer) { observers.remove(observer); } public void notifyObservers() { for (Observer ob : observers) { ob.update(this); } } }
Nesta concretização do padrão, a notificação envia a referência do objecto que foi alterado, por forma a que cada observer que é notificado recebe a referência do objecto alterado (se bem que possa necessitar depois de realizar um downcast para a classe concreta).
A classe Emprestimo necessita de ser alterada por forma a notificar todos as entidades interessadas sempre que a taxa de juro é alterada:
public class Emprestimo extends Subject { // ... public void alteraJuro(float juro) { _juro = juro; notifyObservers(); } //... }
De acordo com a estrutura do padrão, as entidades que estejam interessados em receber uma notificação sempre que as condições de um empréstimo são alteradas são representadas pela entidade abstracta Observer:
interface Observer { void update(Subject subject); }
Cada diferente tipo de observer que exista necessita de concretizar a interface Obeserver, especificando o método update com o comportamento correcto para a entidade em causa. Por exemplo, supondo que a classe Jornal de Economia apenas quer imprimir o novo valor do juro, o código desta classe seria o seguinte:
public class JornalEconomia implements Observer { public void update(Subject sub) { System.out.println("Novo juro: " + ((Emprestimo)sub).obtemJuro()); } }