[英]Observer pattern using generics is too much generic
我使用 Java 中的泛型實現了一個簡單的觀察者模式。
無論如何,現在這個例子之所以有效,只是因為 ConcreteObserver 的update
方法是用所有對象通用的.toString()
方法實現的。
在現實世界中,ConcreteObserver 僅對特定類型的數據進行操作。 例如,如果我的 ConcreteObserver 是播放器,它可以播放 .mp3 或 .avi 但不能播放 .doc。
“強制”將特定類型的數據作為 Observer 和 Observable 之間的合同傳遞的正確方法是什么? 泛型太泛了...
在方法簽名的情況下,我可以使用接口來強制實現特定的簽名。
我可以強制傳遞特定數據類型的方法是什么?
例如:我想要一種由以下組成的數據:
我希望這種數據接口是唯一允許的。
這是我使用泛型的代碼。
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();
這里的問題是您使用的是原始類型:您省略了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>
在Observable<T>
接口及其實現中使用Observer<? super T>
而不是Observer<T>
。 這只是使 API 更靈活一點,因此您可以使用Observer<Object>
(它將接受Integer
參數發送到sendNotify
),而不僅僅是專門的Observer<Integer>
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.