簡體   English   中英

使用泛型的觀察者模式過於泛化

[英]Observer pattern using generics is too much generic

我使用 Java 中的泛型實現了一個簡單的觀察者模式。

無論如何,現在這個例子之所以有效,只是因為 ConcreteObserver 的update方法是用所有對象通用的.toString()方法實現的。

在現實世界中,ConcreteObserver 僅對特定類型的數據進行操作。 例如,如果我的 ConcreteObserver 是播放器,它可以播放 .mp3 或 .avi 但不能播放 .doc。

“強制”將特定類型的數據作為 Observer 和 Observable 之間的合同傳遞的正確方法是什么? 泛型太泛了...

在方法簽名的情況下,我可以使用接口來強制實現特定的簽名。

我可以強制傳遞特定數據類型的方法是什么?

例如:我想要一種由以下組成的數據:

  • 一個字符串
  • 一個 int(下一個二進制數據塊的長度)
  • 一個二進制數據塊
  • 二進制塊的某種元數據描述符

我希望這種數據接口是唯一允許的。


這是我使用泛型的代碼。

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();

這里的問題是您使用的是原始類型:您省略了observerobservable的類型參數。

添加類型參數。 例如,如果您指定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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM