11

私はMVVMを学習しているだけで、計算元の値の変更の結果として、計算されたプロパティへの変更を表示する方法を試しています。私がこれまで見てきた解決策はすべて、カプセル化に重大な違反を犯しており、もっと良いものはないかと考えています。

複雑な税計算の結果を表示する必要があるとします。計算 (およびおそらくその依存関係) は時々変更されるため、厳密にカプセル化しておきたいと思います。

ここで最も頻繁に提供される解決策は、税額が依存するすべてのプロパティを取得して、そのプロパティ自体とそれに依存するすべてのプロパティの ModelView で PropertyChanged を呼び出すことです。つまり、すべてのプロパティは、それを使用する、または使用する可能性のあるすべてのものを知る必要があります。以前は依存していなかったものに計算が依存するように税規則が変更された場合、計算に使用されるすべての新しいプロパティに触れる必要があります (おそらく他のクラスで、おそらく私の管理下ではありません)。税額の PropertyChanged を呼び出してもらいます。それはカプセル化の希望を完全に台無しにします。

私が考えることができる最善の解決策は、計算を行うクラスにPropertyChanged イベントを受け取り、計算に何か変更が加えられたときに税額の新しい PropertyChanged イベントを発生させることです。これにより、少なくともクラスレベルでのカプセル化は保持されますが、それでもメソッドのカプセル化は破られます。クラスは、メソッドがどのように機能するかを知る必要はありません。

それで、私の質問は、より良い方法はありますか(もしそうなら、それは何ですか)?それとも、プレゼンテーションのカプセル化 (MVVM) によって、ビジネス ロジックのカプセル化が妨げられますか? どちらかまたは両方の選択に直面していますか?

4

5 に答える 5

4

Stephen Cleary の計算されたプロパティを確認してください: https://github.com/StephenCleary/CalculatedProperties

これは非常に単純で、トリガー プロパティ セッターを汚染することなく、依存プロパティの通知を伝達します。

原始的な例:

public string Name 
{
  get { return Property.Get(string.Empty); }
  set { Property.Set(value); }
} 

public string Greeting => Property.Calculated(() => "Hello, " + Name + "!");

そのサイズの割には信じられないほど強力です。モデルのプロパティを表示するための Excel のような数式エンジンを考えてみてください。

私はいくつかのプロジェクトでドメイン クラスとビュー モデル クラスの両方でそれを使用しました。命令型制御フロー (エラーの主な原因) のほとんどを排除し、コードをより宣言的で明確にするのに役立ちました。

それについての最もよいことは、依存プロパティが異なるビュー モデルに属することができ、依存グラフが実行時に劇的に変化する可能性があり、それでも機能することです。

于 2017-01-03T13:04:17.037 に答える
3

ここで最も頻繁に提供される解決策は、税額が依存するすべてのプロパティを取得して、プロパティ自体とそれに依存するすべてのプロパティの ModelView で PropertyChanged を呼び出すことです。....

はい、ただしそのオブジェクトのみ: 各プロパティは、セッターで独自のプロパティ変更イベントを発生させる必要があります。さらに、セッターは、その値に依存するプロパティを何らかの方法でトリガーする必要があります。他のオブジェクトの更新をプロアクティブにトリガーしようとしないでください。このオブジェクトをリッスンする必要がありますPropertyChanged

私が考えることができる最善の解決策は、計算を行うクラスに PropertyChanged イベントを受け取り、計算に何か変更が加えられたときに税額の新しい PropertyChanged イベントを発生させることです。これにより、少なくともクラス レベルでのカプセル化は保持されますが、それでもメソッドのカプセル化は破られます。クラスは、メソッドがどのように機能するかを知る必要はありません。

これは確かに標準的な方法です。各クラスには、依存するプロパティを監視し、プロパティのプロパティ変更イベントを発生させる責任があります。

おそらくこれを行うのに役立つフレームワークがありますが、何が起こるべきかを知ることは価値があります.

于 2013-10-25T14:17:02.903 に答える
0

私が考えることができる最善の解決策は、計算を行うクラスがPropertyChanged イベントを受け取るようにし、計算に何か変更が加えられたときに税額の新しい PropertyChanged イベントを発生させることです。これにより、少なくとも クラスレベルでのカプセル化は保持されますが、それでもメソッドのカプセル化は破られます。クラスは、メソッドがどのように機能するかを知る必要はありません。

「カプセル化」という用語を、構文について口論するところまで拡張していると思います。たとえば、ここでは問題はありません。

private int _methodXCalls;
public void MethodX() {
    Console.WriteLine("MethodX called {0} times", ++_methodXCalls);
}

フィールドは MethodX 内でのみ関連しますが、宣言が構文的に内部に MethodXないからといって、メソッドのカプセル化が壊れるわけではありません。

同様に、クラスの初期化で各プロパティのイベント ハンドラーを設定しても問題はありません。初期化時に一度だけ表示され、それらの特定のハンドラーが追加されたことを「知る」ために他に何も必要とされない限り、プロパティは依然として論理的に自己完結型です。おそらく何らかの方法でプロパティの属性を使用できますが[DependsOn(property1, property2)]、これは実際にはコードの読みやすさの問題です。

于 2013-10-25T14:48:57.283 に答える