MVVMのVMにロジックはどこまで含めて良いか

つまるところ ・「プレゼンテーションロジック(とそのステート)」 ・「ドメインロジック(とそのステート)」 とで分けるのだけれど、Web上のコードにはHTTP通信という、ドメインロジックにも使いそうな処理もVMに含まれていたりします。その機微なところをどう扱うかについて意見交換をしました。
3
Hirohito Kato ⌘ @hkato193

MVVMのViewModelを手のひらの上に載せようとしているけれど、納得しきれない部分もあって苦戦中。たとえばVMからHTTP通信を起こしてるのもあるけれど qiita.com/laiso/items/9e… 、どうしてHTTP通信がVMに登場するのか分からない

2017-05-01 11:52:34
Hirohito Kato ⌘ @hkato193

ひとまず「通信はModel層でやろうね」という記述を見つけた。 健康的なMVVM 書いてますか? ~MVVMアンチパターン集~ speakerdeck.com/takasek/jian-k…

2017-05-01 12:23:01
Hirohito Kato ⌘ @hkato193

分からない点は他にもあって、VとVMとをバインドするときに、Rxでいう色んなオペレータを組み合わせているコードもあるけれど、その組み合わせ(=ロジック)を実現するのは誰の責務?というのが分からないです。ビューコントローラでやってたりビューがやっていたり、結構まちまちな気が。

2017-05-01 12:36:05
りず @rizumita

@hkato193 それはたぶんViewControllerという名前ですがViewとしてあつかっているとおもいます。VIPERでもVCをViewに見立てます。そのVMがどのViewの影かを考えてバインドする場所を考えると良いと思います。

2017-05-01 12:45:15
takasek @takasek

@hkato193 おっしゃるとおりです。もちろん正しく分けるならModel層でやるべきなのですが、ただ、開発初期段階だったり、あまり複雑でない画面であれば、とりあえずVMを「最低限UIKitとは縁の切れた世界」と捉えるのも選択肢かなあと思ってはおります。

2017-05-01 12:45:22
takasek @takasek

@hkato193 (ただその資料だいぶ昔に発表したやつなので、実際ふつうにダメな理解で書いちゃってる部分もありそう…のちほど見直してみますね)

2017-05-01 12:46:50
Hirohito Kato ⌘ @hkato193

@rizumita なるほど、VCはViewとして扱うわけですか。他の分からないことに「VとVMは1対1というけれど、Viewの単位って何?ラベルやボタン1つずつじゃないよね」があったのですが、VCを1単位に見立てるのもありかなと思い始めました。…いや、それだと粒度粗すぎるかしら

2017-05-01 12:50:26
Hirohito Kato ⌘ @hkato193

@takasek おおお、 @takasek さんの一連のスライドにはものすごくお世話になってます<(_ _)>。MVVMはWeb上の記事を年代とともに眺めると、当初の対象領域から変わってきているような気がしました。MVCみたいに「いつ・どこのMVVM」で意味合いが変わるのかなあと感じます。

2017-05-01 12:55:44
りず @rizumita

@hkato193 Viewの単位は初めからMVVMの場合はViewControllerのVMをつくって、サブビューが増えるたびにVMを分離していくようにしてます。といっても多くはUITableViewがからんで難しいんですが。

2017-05-01 12:58:24
Hirohito Kato ⌘ @hkato193

@rizumita ここで仰るところのサブビューは、画面遷移をともなわないものも含むのですよね。そして最初は大きな単位で作っておいて、そこから必要に応じて分離していくのですか。参考になります。

2017-05-01 13:03:39
takasek @takasek

@hkato193 光栄です…!プレゼンテーションロジックとドメインロジックの境界、Modelの境界が定まらないと「VM」の定義も定まらないのですよね。自分もやっぱり…ぶっちゃけ雰囲気でMVVMをやっている気がしてなりません。

2017-05-01 13:09:39
もっさりさん @TeamMOSA2

MVVM/MVCに限らず特定の層にコードが偏るのって仕方ないと思うんよね。 臭いものに蓋をしただけのMVVMは救いようがない。

2017-05-01 13:18:16
takasek @takasek

@hkato193 @rizumita MVVMの始まりであるWPFでは、VM→XAMLに直接bindするものでしたね。C# は詳しくないのでイメージ湧いていないですが、iOSとはだいぶ勝手が違うのだろうと想像します。それで、VMはプレゼンテーションロジックの置き場所、で認識は合っていますか?

2017-05-01 17:51:25
りず @rizumita

@takasek @hkato193 プレゼンテーションロジックとそのステートの置き場所ということで、認識はあってると思います。

2017-05-01 17:54:40
takasek @takasek

@rizumita @hkato193 でしたら、論点は最初の「通信をVMで叩いていいか」に絞られますね。多くの画面ってAPIからEntityを受けて表示する程度の機能で、Modelを丁寧に分けてもただのパイプになるだけなので、VMで通信しちゃってもそこまで困らないし将来的な影響も限定的な気がするのですがどうでしょう。

2017-05-01 18:21:14
りず @rizumita

@takasek @hkato193 もしその程度のMでいいならVMを導入する必要もない気がします。なのでやはり私はMVCかなと。

2017-05-01 18:23:37
takasek @takasek

@rizumita @hkato193 ローディング中のハンドリングとかページングとか、受けたEntityによってsectionHeaderを出すとかなんとか、なんだかんだでビジネスロジックとは言いがたいプレゼンテーションロジックが膨らむこともあるので、そういうのを押し込めるVMは、自分は欲しいこと多いです。

2017-05-01 18:40:29
りず @rizumita

@takasek @hkato193 それならやっぱりMは分離したくなりません?

2017-05-01 18:41:04
takasek @takasek

@rizumita @hkato193 さっきの @hkato193 さんの「結局他に誰も使わないModelが増えがちですので」が悩みどころで、「これは確かにビジネスロジックだ」と言えるようになったタイミングで切り出せば良く思えるのです。

2017-05-01 19:14:28
laiso👻 @laiso

@takasek @hkato193 ViewModelで通信を行なわないようにするのが好ましいというのは確かにそうだと思いますけど僕の場合実際の開発では妥協してテスト駆動で設計していくパターンが多いです。テストが書きにくいパターンに陥りそうだったら設計を変える→テストを書くというのを繰替えす仕組みがあればいいかなと

2017-05-01 19:20:25
takasek @takasek

@laiso @hkato193 laisoさんはViewModelも必ずユニットテストやっていますか? プレゼンテーションロジックって、テストコードがプロダクトコードのコピペに近くなったり、目で見たほうが早かったり、改修が多くてテストコードが負担になるパターンも多くて、どこまで割り切るか悩んでいます。

2017-05-01 19:40:58
laiso👻 @laiso

@takasek @hkato193 プロジェクトの性質やフェーズによりますが1人で新規アプリケーションを設計するという現状だと不具合の修正のみテストを残します(ViewModel以外も)。TDDするとしたら「テスト可能な設計にできるか自信ない」という時ですね。手動テストは別途テストケース作っています。

2017-05-01 19:56:24
takasek @takasek

@laiso @hkato193 なるほど、わかりやすいです。

2017-05-01 20:00:58
laiso👻 @laiso

@takasek @hkato193 でも本来データバインディング導入前にはModelにあってテスト書いたコードがViewModelに紛れこんだせいでテスト書かなくなってしまうのは悲劇ですね笑。なのでViewの外に出せるコードは積極的に分離したいのが理想です

2017-05-01 20:07:27
りず @rizumita

@takasek @hkato193 私には関さんがおっしゃるくらいの状態でVMを切り分ける必要性が感じられないので、そのあたりは好みなのかもしれないですね。その点では私はVMよりはMの切り分けは出来るだけ早くするように考えてます。

2017-05-01 20:13:38