我正在尝试学习观察者设计模式,我开始观看属于 codewithmosh 的系列,称为“终极设计模式系列”。
在关于观察者的课程中,他说:
这就是我们所说的“推式”沟通方式。因为 “主体”将变化推送给观察者。
但是,这种方法有一个问题。明天,我们可能会 引入一种新的 ConcreteObserver 类型,该观察者可能需要 一组不同的价值观。所以我们必须回到这里改变 观察者界面;我们可能需要引入一个新参数,或者 我们可能必须更改此处传递的对象。我们必须 在该课程中引入新领域。
所以这个方法不太好 灵活,因为主体正在对这些做出假设 观察员;假设这些观察者在以下情况下需要这些值: 改变发生了。现在,如果每个观察者需要一组不同的 价值观?所以,这就是我们可以使用“拉动”方式的沟通方式。
我只是想理解为什么Push风格不灵活。我的问题是关于这句话:
所以我们要回到这里,改变Observer接口;我们可能 必须引入一个新参数,或者我们可能必须更改对象 这是在这里传递的。我们必须在这方面引入新的领域 上课了。
这是我的具体主题:
public class ConcreteSubject extends Subject {
private int value;
private String value2;
public void setValue(int value) {
this.value = value;
notifyObservers(value, null);
}
public void setValue2(String value2) {
this.value2 = value2;
notifyObservers(null, value2);
}
}
我也有 2 个 ConcreteObserver,但是
ConcreteObserver2
不想收到有关 ConcreteSubject 中第一个字段“value
”的通知。我尝试引入一个像这样的新参数:
public interface Observer {
<T, U> void update(T value, U value2);
}
这些是我的其他课程:
public class Subject { // Observable
private List<Observer> observers = new ArrayList<>();
public void addObserver(Observer observer) {
observers.add(observer);
}
public void removeObserver(Observer observer) {
observers.remove(observer);
}
public <T, U> void notifyObservers(T value, U value2) {
for (Observer observer : observers)
observer.update(value, value2);
}
}
--
public class ConcreteObserver1 implements Observer {
@Override
public <T, U> void update(T value, U value2) {
if (value != null)
System.out.println("ConcreteObserver1 got notified. " + value);
if (value2 != null)
System.out.println("ConcreteObserver1 got notified. " + value2);
}
}
--
public class ConcreteObserver2 implements Observer {
@Override
public <T, U> void update(T value, U value2) {
if (value2 != null)
System.out.println("ConcreteObserver2 got notified. value2 is: " + value2);
}
}
所以这是老师谈到的第一个解决方案,它引入了一个新参数,这是我对此解决方案的实现,但我无法理解第二个解决方案。 (粗体文字)
当他说“我们可能必须更改传递过来的对象”时,这是什么意思?我认为它没有用,因为我的接口中的参数类型是通用的,我可以传递任何我想要的东西。我也无法理解“我们必须在该类中引入新领域”。在哪个级别?为什么?这如何帮助 ConcreteObserver2 收到有关特定字段的通知?
如果您的设计取决于观察者需要了解消息的内容,则应该使用拉动风格。因为总是有可能为了观察者而改变消息契约。换句话说,您的消息契约取决于观察者,因为他们消费消息。这样,改变观察者(消费者)的需求会导致消息契约的改变,这并不是一个很好的耦合。消费者这边更容易发生改变。因为可能会有新的消费者,而现有的消费者可能会随着时间的推移而改变。
当消息契约依赖于Subject时,应该使用观察者设计模式。在这个概念中,主题决定了消息契约的结构是什么。例如,它非常适合与事件一起使用。事件表明某事发生了。他们不关心谁使用这些数据,他们只是广播事件数据。