gpt4 book ai didi

java - 使用泛型的观察者模式过于泛型

转载 作者:行者123 更新时间:2023-12-01 19:28:30 25 4
gpt4 key购买 nike

我使用 Java 中的泛型实现了一个简单的观察者模式。

无论如何,现在该示例之所以有效,只是因为 ConcreteObserver 的 update 方法是使用所有对象通用的 .toString() 方法实现的。

在现实世界中,ConcreteObserver 仅对特定类型的数据进行操作。例如,如果我的 ConcreteObserver 是一个播放器,它可以播放 .mp3 或 .avi,但不能播放 .doc。

“强制”特定类型的数据作为观察者和可观察对象之间的契约传递的正确方法是什么?泛型太通用了......

对于方法签名,我可以使用接口(interface)来强制实现特定签名。

我可以通过哪种方式强制传递特定数据类型

例如:我想要一种由以下组成的数据:

  • 字符串
  • int(下一个二进制数据 block 的长度)
  • 一个二进制数据 block
  • 二进制 block 的某种元数据描述符

我希望这种数据接口(interface)是唯一允许的。

<小时/>

这是我使用泛型的代码。

public interface Observable<T> {
public void add(Observer<T> observer);
public void remove(Observer<T> observer);
public void sendNotify(T notification);
}

public class ConcreteObservable<T> implements Observable<T> {

ArrayList<Observer<T>> observerList = new ArrayList<>();

public void add(Observer<T> observer){
observerList.add(observer);
}

public void remove(Observer<T> observer) {
observerList.remove(observer);
}

public void sendNotify(T notification) {
for (Observer observer : observerList) {
observer.update(notification);
}
}
}


public interface Observer<T> {
public void update(T value);
}

public class ConcreteObserver<T> implements Observer<T> {

@Override
public void update(T value) {
System.out.println(value.toString());
}
}

public static void main(String[] args) {

ConcreteObservable observable = new ConcreteObservable();
ConcreteObserver observer = new ConcreteObserver();
observable.add(observer);

int value = 5;
observable.sendNotify(value);

String string = "Test";
observable.sendNotify(string);

}

最佳答案

ConcreteObservable observable = new ConcreteObservable();
ConcreteObserver observer = new ConcreteObserver();

这里的问题是您正在使用 raw types :您省略了 observer 上的类型参数和observable .

添加类型参数。例如,如果您指定 Integer ,您将无法通过 String参数:

ConcreteObservable<Integer> observable = new ConcreteObservable<>();
ConcreteObserver<Integer> observer = new ConcreteObserver<>();

observable.add(observer); // Fine.

int value = 5;
observable.sendNotify(value); // Fine.

String string = "Test";
observable.sendNotify(string); // Error!

您的 IDE 或编译器将向您发出有关使用原始类型的警告:请注意它们(您的代码中还有其他原始类型)。

<小时/>

另请注意,您可以使用 Observer<? super T>而不是Observer<T>在你的Observable<T>接口(interface)及其实现。这只是使 API 更加灵活,因此您可以使用 Observer<Object> 等。 (它将接受 Integer 参数到 sendNotify ),而不仅仅是专门的 Observer<Integer> .

关于java - 使用泛型的观察者模式过于泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60609455/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com