2010-11-01 98 views
1

我正試圖在基於消息傳遞的系統中管理多個模型。每個模型可能具有依賴於其他模型的值。例如:管理多個相互依賴的模型

public class V2Model : BaseModel 
    { 
     private int mSomeVal; 
     private byte mSomeByte; 

     // … 

     // Update mSomeByte based on multiple models values 
     public void SetMultipleDependecyValue(int someIntFromModel1, short someShawteeyFromModel3) 
     { 
     mSomeByte = Convert.ToByte((someShawteeyFromModel3/someIntFromModel1) + mSomeVal); 
     } 
    } 

我也想用MVC模式,但不是通過模型實例,我想我會通過在一個「庫」的實例。 'Repository'實例將充當處理所有Model實例的管理器。其結果將是這個樣子:

public class V1Controller<ViewType, ModelType> 
     where ViewType : IV1View 
     where ModelType : BaseModel 
    { 
     ViewType mView; 
     BaseRepository mBaseRep; 

     public V1Controller(ViewType view, BaseRepository rep) 
     { 
     mView = view; 
     mBaseRep = rep; 
     mBaseRep.GetModel<ModelType>().PropertyChanged += new PropertyChangedEventHandler(V1ModelPropertyChanged); 
     } 

     void V1ModelPropertyChanged(object sender, PropertyChangedEventArgs e) 
     { 
     switch (e.PropertyName) 
     { 
      case "SomeVal": 
       // Update the view 
       int some_val = mBaseRep.GetModel<ModelType>().SomeVal; 
       mView.HexSomeValue = some_val; 
       // Oh BTW, we know V2Model's value depends on this... update it with V1Model and V3Model's values 
       short some_short = mBaseRep.GetModel<V3Model>().SomeShawteey; 
       mBaseRep.GetModel<V2Model>().SetMultipleDependecyValue(some_val, some_short); 
       break; 
     } 
     } 

     public void UpdateVal(int someValue) 
     { 
     mBaseRep.GetModel<ModelType>().SomeVal = someValue; 
     } 
    } 

在這種情況下,如果V1Model的性質變了,V1ModelPropertyChanged,我就知道V2Model的對象上的依賴,並用適當的值更新。處理這種相互依存的模型方案有沒有更好的方法,或者這是一個可接受的解決方案?我沒有真正尋找任何第三方。

+0

它是web還是WPF/SL? – Aliostad 2010-11-01 14:19:43

+0

它是Winforms。 – SwDevMan81 2010-11-05 15:29:57

+2

K.I.S.S.發生了什麼事作爲設計模式?你能否抽象地解釋你想要在沒有代碼的情況下實現什麼?也許有一個比你剛開始的解決方案更簡單的解決方案。 – 2010-11-06 19:11:34

回答

1

如果你想處理這個優雅,你將需要有一些組件跟蹤模型之間的依賴關係。當一個屬性發生變化時,您將遍歷該屬性的所有依賴關係,然後適當地更新它們。

也許你的BaseRepository可能會引用DependencyManager類。該班級必須列出所有相互依賴的房產。

一個簡單的實現可能是這樣的:

class PropertyDescriptor 
{ 
    public Type ModelType { get; set; } 
    public string Property { get; set; } 
} 

class DependencyManager 
{ 
    private Dictionary<PropertyDescriptor, List<PropertyDescriptor>> _dependencies = new Dictionary<PropertyDescriptor, List<PropertyDescriptor>>(); 

    public void RegisterDependency(PropertyDescriptor property, PropertyDescriptor dependentProperty) 
    { 
     if (!_dependencies.ContainsKey(property)) 
     { 
      _dependencies.Add(property, new List<PropertyDescriptor>()); 
     } 
     _dependencies[property].Add(dependentProperty); 
    } 

    public IEnumerable<PropertyDescriptor> GetDependentProperties(PropertyDescriptor property) 
    { 
     if (!_dependencies.ContainsKey(property)) 
     { 
      yield break; 
     } 
     else 
     { 
      foreach (PropertyDescriptor p in _dependencies[property]) 
      { 
       yield return p; 
      } 
     } 
    } 
} 

然後,當你發現一個屬性的變化,你可以查詢DependencyManager的還有什麼需要改變。但是在級聯時要小心檢查循環依賴關係!

+0

感謝您的建議,這絕對是一個可能的解決方案。 – SwDevMan81 2010-11-09 20:32:25

1

也許我錯過了一些東西,但是這不是observer pattern的用途嗎?如果您將模型設置爲彼此的觀察者(即使用委託或事件),那麼控制器應該能夠保持對相關性的無知。

+0

+1,除非我也失去了一些東西......雖然我覺得在.NET中使用事件/代表會更優雅。 – Crisfole 2010-11-10 17:55:58

+0

這意味着每個模型都會收到關於每個PropertyChanged事件的通知,即使他們不關心它。想象一下在model1中屬性發生變化的場景,該變化會通知所有模型有關該變化,這會更改model2中的值。模型2中的這種改變會通知所有模型,並且繼續。它不是最直接的方式。我正在尋找一個解決方案,說,嘿這個屬性剛剛改變,這個其他模型有一個值,根據該值計算,去更新它。 – SwDevMan81 2010-11-10 18:15:34

+0

一般而言,您需要這種行爲,以便隨着模型的發展,他們可以決定他們關心的信息,而無需改變其他模型或控制器。添加一個新的依賴字段/屬性然後意味着你只更改一個模型/類而不是兩個(你正在更新的模型加上它所依賴的模型),甚至三個(你正在更新的模型,它依賴的模型和控制器)。 – 2010-11-10 21:35:01