Czytałem ostatnio o wzorcu Observer. Z tego co wyczytałem obiekty sa "loosely coupled ". I dajmy na to mam coś takiego :
public interface Subject {
void register(Observer observer);
void unregister(Observer observer);
void notifyAllObservers();
}
public class PaperShop implements Subject {
private int costOfBook = 0;
private int costOfMagazine = 0;
private ArrayList<Observer> observers;
public PaperShop() {
observers = new ArrayList<Observer>();
}
@Override
public void register(Observer observer) {
observers.add(observer);
}
@Override
public void unregister(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyAllObservers() {
for(Observer observer:observers) {
observer.update(costOfBook, costOfMagazine);
}
}
public void setCostOfBook(int costOfBook) {
this.costOfBook = costOfBook;
notifyAllObservers();
}
public void setCostOfMagazine(int costOfMagazine) {
this.costOfMagazine = costOfMagazine;
notifyAllObservers();
}
}
public interface Observer {
void update(int costOfBook, int costOfMagazine);
}
public class House implements Observer {
private int costOfBook = 0;
private int costOfMagazine = 0;
@Override
public void update(int costOfBook, int costOfMagazine) {
this.costOfBook = costOfBook;
this.costOfMagazine = costOfMagazine;
}
public int getCostOfBook() {
return costOfBook;
}
public int getCostOfMagazine() {
return costOfMagazine;
}
}
i bez problemu moge dodawać kolejne klasy Observer, ale problem pojawia się gdy dodam do klasy implementujacej subject nowe pole np costOfNotebook. Motoda update jest podana tak na "sztywno" . Gdybym miał np tysiąc observerów to w każdej bym musiał ją zmienić. Mógłbym także zrobić w ten sposób :
...
@Override
public void notifyAllObservers() {
for(Observer observer:observers) {
observer.update();
}
}
a observera tak :
public class House1 implements Observer {
private int costOfBook = 0;
private int costOfMagazine = 0;
private Subject subject;
public House1(Subject subject) {
this.subject = subject;
}
@Override
public void update() {
costOfBook = subject.getCostOfBook();
costOfMagazine = subject.getCostOfMagazine();
}
}
ale teraz każdą metode musze mieć w interfejsie Subject, a przecież Subject może być np sklepem samochodowym i po co implementować metody takie jak costOfBook.
Czy jest jakiś lepszy sposób na rozwiązanie tego ?