62

MVVM パターンを使用していくつかのプロジェクトを実行した後、私はまだ ViewModel の役割に苦労しています。

過去に行ったこと: モデルをデータ コンテナーとしてのみ使用する。ViewModel でデータを操作するためのロジックを配置します。(それがビジネス ロジックですよね?) 短所: ロジックは再利用できません。

私が今試していること: ViewModel をできるだけ薄く保つ。すべてのロジックをモデル レイヤーに移動します。ViewModel にはプレゼンテーション ロジックのみを保持します。短所:モデルレイヤー内でデータが変更された場合、UI通知が非常に苦痛になります。

したがって、より明確にするために例を示します。

シナリオ: ファイルの名前を変更するツール。クラス: File : 各ファイルを表します。ルール: ファイルの名前を変更するロジックが含まれています。

アプローチ1に従っている場合:ファイル、ルール、およびビューのViewModelの作成-> RenamerViewModel。すべてのロジックを RenamerViewModel に入れる: FileViewModel と RuleViewModel のリストと、先行するロジックを含みます。簡単で高速ですが、再利用できません。

アプローチ2に従っている場合:新しいモデルクラスの作成->ファイルのリストを含むリネーム、ルール、および各ファイルを相互に処理し、各ルールを適用する進行中のロジック。File、Rule、Renamer の Viewmodel を作成します。現在、RenamerViewModel には Renamer Model のインスタンスと、Renamer のファイルとルール リストをラップする 2 つの ObservableCollections のみが含まれています。しかし、ロジック全体は Renamer モデルにあります。そのため、Renamer モデルがメソッド呼び出しによって一部のデータを操作するためにトリガーされた場合、ViewModel にはどのデータが操作されるかの手がかりがありません。モデルには PropertyChange 通知が含まれていないため、それを回避します。そのため、ビジネス ロジックとプレゼンテーション ロジックは分離されていますが、これにより UI への通知が難しくなります。

4

4 に答える 4

67

ビューモデル内にビジネス ロジックを配置することは、物事を行う上で非常に悪い方法です。そのため、決してそうしないでくださいとすぐに言い、2 番目のオプションの議論に移ります。

モデル内にロジックを配置する方がはるかに合理的であり、最初のアプローチとしては適切です。欠点は何ですか?あなたの質問は言う

そのため、Renamer モデルがメソッド呼び出しによって一部のデータを操作するためにトリガーされた場合、ViewModel にはどのデータが操作されるかの手がかりがありません。モデルには PropertyChange 通知が含まれていないため、それを回避します。

まあ、モデルを実装INotifyPropertyChangedすることで、より良いものに進むことができます。ただし、それができない場合もあるのは事実です。たとえば、モデルは、プロパティがツールによって自動生成され、変更通知を発生させない部分クラスである場合があります。それは残念なことですが、世界の終わりではありません。

何かを購入したい場合は、誰かがその代金を支払わなければなりません。そのような通知を行うモデルでない場合は、次の 2 つの選択肢しかありません。

  1. ビューモデルは、モデルのどの操作が (おそらく) 変更を引き起こすかを認識しており、そのような操作が行われるたびにその状態を更新します。
  2. 他の誰かがどの操作が変更を引き起こすかを知っており、ビューモデルが変更をラップしているモデルの後にその状態を更新するようにビューモデルに通知します。

最初のオプションも悪い考えです。実際には、ビューモデル内に「ビジネス ロジック」を配置することになるからです。ビューモデルにすべてのビジネス ロジックを配置するほど悪くはありませんが、それでもそうです。

2 番目のオプションは、より有望です (残念ながら、実装にはさらに多くの作業が必要です)。

  • ビジネス ロジックの一部を別のクラス (「サービス」) に配置します。このサービスは、必要に応じてモデル インスタンスを操作することで、実行するすべてのビジネス オペレーションを実装します。
  • これは、モデルのプロパティが変更される可能性がある時期をサービスが認識していることを意味します (これで問題ありません: モデル + サービス == ビジネス ロジック)。
  • このサービスは、変更されたモデルに関する通知をすべての関係者に提供します。ビューモデルはサービスに依存し、これらの通知を受け取ります (そのため、「自分の」モデルがいつ更新されたかがわかります)。
  • ビジネス オペレーションもサービスによって実装されるため、これは非常に自然なままです (たとえば、コマンドがビューモデルで呼び出されると、その反応はサービスの適切なメソッドを呼び出します。ビューモデル自体はビジネス ロジックを認識していないことを思い出してください)。

このような実装の詳細については、私の回答hereおよびhereも参照してください。

于 2013-05-02T13:10:16.547 に答える
13

どちらのアプローチも有効ですが、モデルと VM レイヤーの間にサービスを実装する 3 つ目のアプローチがあります。モデルを馬鹿げたままにしたい場合、サービスは、再利用可能な方法でビジネス ルールを適用できる UI に依存しない仲介者を提供できます。

モデルには PropertyChange 通知が含まれていないため、それを回避します

なぜこれを避けているのですか?誤解しないでいただきたいのですが、私は自分のモデルを可能な限り馬鹿げたものにする傾向がありますが、モデルに変更通知を実装すると便利な場合があり、実装する場合にのみ依存System.ComponentModelします。これは完全に UI に依存しません。

于 2013-05-02T13:10:03.867 に答える