1


2

複数の相互依存モデルの管理

メッセージングベースのシステムで複数のモデルを管理しようとしています。 各モデルには、他のモデルに依存する値がある場合があります。 例えば:

   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パターンも使用したいのですが、Modelインスタンスを渡す代わりに、「Repository」インスタンスを渡すと思いました。 「リポジトリ」インスタンスは、すべてのモデルインスタンスを処理するマネージャーとして機能します。 結果は次のようになります。

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

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

      void V1ModelPropertyChanged(object sender, PropertyChangedEventArgs e)
      {
         switch (e.PropertyName)
         {
            case "SomeVal":
               // Update the view
               int some_val = mBaseRep.GetModel().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().SomeShawteey;
               mBaseRep.GetModel().SetMultipleDependecyValue(some_val, some_short);
               break;
         }
      }

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

この状況で、V1Modelのプロパティが変更された場合、V1ModelPropertyChangedで、V2Modelのオブジェクトへの依存関係を知り、適切な値で更新します。 この相互依存モデルスキームを処理するより良い方法がありますか、これは許容可能な解決策でしょうか? サードパーティを探しているわけではありません。

2 Answer


1


これをエレガントに処理したい場合は、モデル間の依存関係を追跡するコンポーネントが必要になります。 プロパティが変更されると、そのプロパティのすべての依存関係を反復処理し、適切に更新します。

おそらく、あなたの BaseRepository`は DependencyManager`クラスへの参照を保持しているかもしれません。 そのクラスには、互いに依存するすべてのプロパティのリストが必要です。

簡単な実装は次のようになります。

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

class DependencyManager
{
    private Dictionary> _dependencies = new Dictionary>();

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

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

次に、プロパティの変更を検出すると、他に変更が必要なものについてDependencyManagerにクエリできます。 ただし、カスケードするときは循環依存関係を確認するように注意してください!


1


たぶん何かが足りませんが、これはhttp://en.wikipedia.org/wiki/Observer_pattern[observer pattern]の目的ではありませんか? モデルを互いのオブザーバーとして設定する場合(つまり、デリゲートまたはイベントを使用する場合)、コントローラーは依存関係を至福の無知のままにすることができます。