2009-08-07 76 views
3

假設你有在一定查看感興趣的模型5個或6個變量,你寫的每一個不同的功能,如在MVC中通知觀察者的最佳方式?

int a; 
int b; 
int c; 

void setA(newA) { 
    a = newA; 
    notifyAObservers(); 
} 

void setB(newB) { 
    b = newB; 
    notifyBObservers(); 
} 

void setC(newC) { 
    b = newC; 
    notifyCObservers(); 
} 

或者你只是有一個通知方法,浪費一點點CPU時間

即代替notifyAObservers和notifyBObservers,你就必須notifyObservers

回答

6

相信traditional approach是通知所有觀察者,並讓他們處理。這是因爲你不知道哪些觀察者正在觀察哪個變量 - 你只知道他們想在事情發生變化時得到通知。但是,如果你確實知道觀察者觀察哪些變量,並且表現是至關重要的,那麼你可以做一些你喜歡的事情。

在傳統的觀察者模式中,觀察者實現了一個update()方法,當發生更改時由控制器調用。 Observable(數據模型)將有一個notifyObservers()方法,它遍歷Observers並調用它們的update()方法。然後,觀察者得到他們需要的和視圖更新。

但是,任何時候我已經實現了觀察者模式,我只是保留一個觀察者列表並通知他們所有人。這樣,我只有一個觀察員列表,其餘的班級以及不同的觀察員都可以更改,而不需要對可觀察班級通知進行任何更改。

+0

這也使事情變得簡單,因爲有正在觀察哪個變量找出哪些觀察員的方式。然而,這可能最終看起來很複雜。 – mnuzzo 2009-08-07 17:54:39

+0

你能舉個托馬斯的例子嗎?我已經投票支持你,但在View中將實施哪些方法,他們將如何得到通知等等。謝謝! – DevDevDev 2009-08-07 18:02:29

+0

您的意思是說,所有的觀察者都會實現一個「notify()」方法,然後他們會針對他們每次感興趣的數據輪詢模型。例如,notifyObservers()只是直接遍歷Observers列表並調用notify()。每個觀察者從模型中提取想要的數據並相應地更新其視圖。就像變量A被改變一樣,B-Observers仍會得到notify()調用,並且會說類似 b = model.getB(),儘管b沒有改變? – DevDevDev 2009-08-07 18:04:40

0

編輯:我幾年前寫了我的答案。剛看完之後,我覺得我需要更新它。

我認爲最好的辦法是通知所有觀察者,並讓意見決定是否需要更新自己..

每個視圖將能夠驗證模型的狀態,並採取相應的行動。 此外,「參數」可以用作一個標誌來指示發生了什麼變化(視圖可能不希望爲每一個小的變化更新自己)。

這樣,模型真的不知道如何以及視圖顯示什麼,它們是分離的。

第一種實現是這樣的:

public class MyModelV1 extends Observable { 
    private int value; 
    public void setValue(int value) { 
     this.value = value; 
     setChanged(); 
     notifyObservers(); 
    } 
    public int getValue() { 
     return value; 
    } 
} 
public class MyViewV1 implements Observer { 
    public void update(Observable o, Object arg) { 
     if (o instanceof MyModelV1) { 
      System.out.println(((MyModelV1) o).getValue()); 
     } 
    } 
} 

的觀點簡單地檢查收到的可觀察的類型。 但是,如果模型具有許多屬性並觸發許多不同場景的視圖,則此簡單檢查可能會頻繁刷新視圖。

另一種方法是如下:

public class MyModelV2 extends Observable { 
    private int value; 
    public void setValue(int value) { 
     this.value = value; 
     setChanged(); 
     notifyObservers("value"); 
    } 
    public int getValue() { 
     return value; 
    } 
} 
public class MyViewV2 implements Observer { 
    public void update(Observable o, Object arg) { 
     if (o instanceof MyModelV2 && "value".equals(arg)) { 
      System.out.println(((MyModelV2) o).getValue()); 
     } 
    } 
} 

這裏,通知通過資格賽,這讓觀點判斷更準確時對自己進行刷新。 該視圖仍然需要檢查並轉換模型,因爲沒有保證arg「value」未被另一個模型通知(並且轉換在運行時會失敗)。

我個人最喜歡的是類似的規定:

public class MyModelV3 extends Observable { 
    private int value; 
    public void setValue(int value) { 
     this.value = value; 
     setChanged(); 
     Notification.MY_MODEL_VALUE_UPDATED.notifyObserver(this); 
    } 
    public int getValue() { 
     return value; 
    } 
} 
public class MyViewV3 implements Observer { 
    public void update(Observable o, Object arg) { 
     if (Notification.MY_MODEL_VALUE_UPDATED.equals(arg)) { 
      MyModelV3 model = Notification.MY_MODEL_VALUE_UPDATED.getModel(o); 
      System.out.println(model.getValue()); 
     } 
    } 
} 
public class Notification<T extends Observable> { 
    public static final Notification<MyModelV3> MY_MODEL_VALUE_UPDATED = new Notification<MyModelV3>(); 
    private Notification() { 
    } 
    public T getModel(Observable o) { 
     return (T) o; 
    } 
    public void notifyObserver(T observable){ 
     observable.notifyObservers(this); 
    } 
} 

這裏,通知發出一個強類型的預選賽中,這勢必示範。 視圖能夠使用通知檢索強類型模型(而不是強制轉換)。

這是什麼地方的觀察者和事件總線之間..