質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

MVVM

MVVM(Model View ViewModel)は構築上のデザインパターンで、表現ロジック(ViewModel)によってデータ(Model)からページ(View)を分離させます。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

2回答

4858閲覧

MVVMの「ViewModelはViewを知ってはいけない」の意図を知りたい。

Y...M

総合スコア18

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

MVVM

MVVM(Model View ViewModel)は構築上のデザインパターンで、表現ロジック(ViewModel)によってデータ(Model)からページ(View)を分離させます。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

0クリップ

投稿2020/09/17 00:17

編集2020/09/18 05:25

MVVMで言われている、「ViewModelはViewを知ってはいけない(依存してはいけない)」というのは、
Viewが持つインスタンスをViewModelが使用することを問題としており、
System.Windows.MediaのDrawingGroupやSystem.Windows.ShapesのRectangleなどをViewModel内で使用し、Viewに公開することは問題ではない理解で合っていますか?
(System.Windows.ShapesのRectangleを使うことは無いかもしれませんが…)

以下のような記事をいくつか読みました。
https://note.com/sigsky/n/n0617c2a2cb60

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2020/09/17 01:01

出典を明示してください
hihijiji

2020/09/17 01:35

✖ ViewModelはViewを知ってはいけない ○ ViewModelはViewに依存してはいけない ですね。
hihijiji

2020/09/18 07:02

ご提示のリンク先はあくまでも個人の学習過程を綴ったものであり、リファレンスとして利用するのはお勧めできません。 古い著作ですが、一番お勧めするのはここ↓です。 https://www.atmarkit.co.jp/fdotnet/chushin/greatblogentry_02/greatblogentry_02_01.html VMでインスタンスを保持すること自体は問題ないですよね。 そのクラスの名前空間がSystem.Windows.Shapesだったとしても VMでレイアウトなど中身をゴリゴリするんじゃなければ問題ないです。
guest

回答2

0

ベストアンサー

依存とは

たとえばユーザープログラマーがライブラリのクラスを使う時、このユーザーの書いたコードはそのライブラリに依存します。

ライブラリがバージョンアップした場合、ユーザーはそれに対応するためにコードを書き直す必要にせまられることがあります。これを「ユーザーのコードはそのライブラリに依存している」と言います。

しかし逆に、ユーザがいくら自分のコードをバージョンアップしても、ライブラリの作者はライブラリに手を入れる必要はありません。これを「そのライブラリはユーザーの書いたコードに依存していない」と言います。

相互依存

このように依存が片方から片方の場合、依存している方のバージョンアップに依存されている方は付き合う必要がありません。

しかし、お互いに依存した場合はどうなるでしょうか?

特に結合が密であればあるほど問題は深刻になりますが、片方がバージョンアップすればもう片方はそれに従ってバージョンアップしなければいけません。

するとそのバージョンアップに従ってもう片方が更にバージョンアップし、それに従ってもう一方的が更に更にバージョンアップし……と、さながらトランプの塔のように、どこか一カ所崩れたら全て崩れる様相になります。

これが相互依存です。

これを避けるため、プログラマーはコードをモジュール化し、相互依存を無くし、結合を疎にするのです。

View と ViewModel

さて View と ViewModel の関係ですが、V は VM のメソッド(あるいはコマンド)を呼び、プロパティを変更します。ユーザーコードがライブラリを呼ぶのと同じ関係ですね。つまり、V は VM に依存します。

ここで VM が V に依存するとどうなるでしょうか。

相互依存になりますね。

相互に依存しても最初のうちは問題になりません。しかし、後から手を入れる際の労力が半端なく大きいものになる可能性があります。

投稿2020/09/18 06:48

編集2020/09/18 06:51
Zuishin

総合スコア28669

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

質問の回答になっているかはわかりませんが。
以下個人的な意見なので反論はご自由にどうぞ。

C# WPFというタグがついているのでRxProperty(他にもバインディングライブラリあるのかどうか知りませんが)を使ってデータバインディングしているものと推測。

単体テストに重点を置くと、オブジェクトどうしは疎結合であるのが望ましい。
MVVMの利点はデータバインディング。
もし、データバインディングをしないならMVVMは選択しません。

オブジェクトのテスト(メソッドやプロパティ)は簡単なのでViewModelの単体テストを書けます。
逆にUIテストは難しい。
VMのプロパティをどのUIコンポーネントで表現するかはViewの仕事なのでViewのオブジェクト(たとえばTextBox)などをVMで扱うのは御法度です。

以上が、前提。

System.Windows.MediaのDrawingGroupやSystem.Windows.ShapesのRectangleなどをViewModel内で使用し、Viewに公開することは問題ではない理解で合っていますか?

基本的にはプリミティブ型といった基本的な型のみVMで扱うのが好ましいですが、どうしても他の値に依存して計算されるもの
たとえば入力エラーがあれば背景色を赤にしたいのでColorなどを扱うなどのは仕方がない。
要は直接 View.xxxx = xxxxx というViewに値を直接代入するコードをなくすことが大事。
値をTextBoxで持ってしまうと、TextBoxはObservableになり得ないのでイベントの連鎖ができず、VMの背景色を変えられない。(TextChangedなんていちいちハンドリングしてられるか)

公開可能なもの=バインディング可能なものであればどのnamespaceのクラスでも使ってもいいとは思いますが、バインディングできずにUI色の強いロジックを書かざるを得ない場合(メッセージボックスを出すとか)、自分ならVMに書かずにController側(WPFだとWindow?でしたっけ?)にコードを入れる。
Rxを使ってるならダイアログのはい・いいえをSuccess/Failureに割り当ててObservable/SingleをflatMapで連鎖させるのも有といえば有。ダイアログのObservableをMockにすれば単体テスト通せるので。

正直 WindowsのMVVMは使いにくい印象
他のプラットフォームのMVVM(iOS/Android/JS)も経験されると理解は深まるのではないでしょうか。

投稿2020/09/17 01:59

honto

総合スコア34

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問