こんにちは。エクセルソフトの田淵です。
2015/12/17(木) に JXUGC #9 として Xamarin.Forms Mvvm 実装方法 Teachathon を開催しました。
振り返り
このネタを前回の JXUGC #6 の懇親会で頂きまして、Xamarin に詳しい方々を先生としてお呼びして、Mvvm について色々教えてもらおう。ということになりました。1ヶ月半前から準備を開始し、先生方をスカウトし、どんなネタをやるのが良いのか Slack でディスカッションしながら形を決めていきました。
- Slack チャットログ
このログにもかなりの知見が詰まっていますので、気になる方は @xmjxug にダイレクトメッセージか、xm.jxug@gmail.com にメールで、Slack アカウントで使っている/使いたいメールアドレスをご連絡ください。ご招待します。そのうちエクスポートして何らかの形で公開しますね。
内容ですが、サンプルアプリとして、ストップウォッチを田淵が作成することになりました。仕様は次のような感じです。
- Start/Stop ボタン、Lap ボタン
- StartするとラップボタンはEnable.ストップするとDisable
- スタートしてからの経過時間をXX'XX.XXXみたいな感じで表示
- 履歴をListViewで残す
- ストップしたら結果をダイアログで出して分岐?
- 今までのラップよりMin, Maxなどをダイアログに表示して次のページに遷移
- スイッチの切り替えで、ミリ秒の桁を表示/非表示
最後のスイッチが私のような素人にはとてもむずかしく、苦労しました。(実際に完全には実装できませんでした。)
私のうんコードは こちら です。
イベント・ドリブンな感じではなんとか動作するようにもっていけましたが、Mvvm 的に頑張って書いたやつはボロボロでしたねw
次のような点を教えていただきました。ペアプロしてもらっているかのような愛のあるマサカリは心地よくすらあり…w
コードビハインドなやつへのマサカリ
- Device.StartTimerは画面の更新とは別なので、500ミリ秒とかで良いのでは?
- AppにStaticとしてもつのは設計上お勧めできないことが多い
- ユーザー毎にViewModelを持ちたい場合とかどうする?→どうしましょう…?w
- 変換するだけのメソッドならUtil的なフォルダにStaticで用意するのはどうか?→ そもそもモデルなどでその変換をすべき
Mvvm 的なやつへのマサカリ
- えっ!?CommandParameter をバインディングしちゃうの?
- Command で条件分岐させてStart/Stopしようと思ったのですが、ボタンの状態を保持しておくと良さそうな感じ?
- CommandパラメーターでViewのテキストを受け取って分岐してるけど、そんなことしなくても状態によって分岐すればOKですかね
- CommandからCommandを呼ぶ必要ないよね?
- メソッドを呼ぶ
- StopwatchMilliSecondsはViewから参照されていないので、INotifyPropertyChangedいらないよね?
- その通りです…
- ConverterParameterに上のCommandParameterと同じようにBindingしようと思ったらBindablePropertyじゃないのでバインドできないそうです
- Converterってそもそも分岐とかを挟むものではない気がする。とのこと。なるほど。。
- ViewのMessageCenter.Subscribeでコード書きすぎ
- 渡す前にVM側で変換するなどしましょう。
- 次のページを表示する方法が分からない
- Xamarin.Forms だけでやるなら MessageCenter でやり取りすることになると思う。とのこと。
- <ContentPage.BindingContext><vm:MainViewModel /> ではなく、コードビハインドに
this.BindingContext = new MainViewModel();
した方が良いよ。- Viewとコードの分離をより厳粛にするなら。
こんなところでしょうか。個人的に感じたのは、イベント・ドリブン的なコード、考え方を Model や ViewModel にそのまま持ってくると当然ですがよろしくなくて、自身の状態を管理するなどよりオブジェクトであることを意識して各オブジェクトを作らないとそれっぽくならないんだろうな。と感じました。
じゃあ、同じストップウォッチのコードを先生方が書くとどうなるの?ということで、発表順に。
先生方のストップウォッチ
- @moonmile さん
- moonmile/JXUG
- ストップウォッチの機能を Model、ViewModel に持った場合の書き方などが盛り込まれたサンプルです。
- 解説まで書いてくださいました!ありがとうございます! JXUG で話した MVVM の活用の解説を | Moonmile Solutions Blog
- @ailen0ada さん
- ailen0ada/RxUISimpleTimer
- Xamarin.Mac の人による WPF, WinForm(!), Xamarin.Mac で ReactiveUI を使ったサンプルです。
- @omanuke さん
- omanuke/StopwatchMVVM
- 皆さんは業務で F# を使っていると思うんですが。のサンプルです。
- @okazuki さん
- runceel/JXUG
- @neuecc さん、@xin9le さんと @okazuki さんが作っている ReactiveProperty を使ったサンプルです。
- ReactiveProperty については MVVMをリアクティブプログラミングで快適にReactiveProperty v2.3オーバービュー - かずきのBlog@hatena ここらへんですかね?
番外先生
- @amay077 さん
- amay077/StopWatchSample
- 言わずと知れた愛知の猛者が「Stopwatch 作ろうかな」と呟いていたので、お願いしたら作ってくださいました!w ありがとうございます!>< RxJava + MVVM パターンで作るストップウォッチアプリ - Qiita しかも詳細な解説付き!分かりやすい!
この後は
先生に私のコードを直してもらうのも面白いのでは?というご意見を頂きましたので、先生として参加された @espresso3389 さんに直していただこうかな…w
@amay077 さんも期待しています♪
僕もストップウォッチ作ってみるかー
— ジェットあめいカスタム (@amay077) 2015, 12月 17
ストリーミングについての振り返り
ストリーミングについてですが、先生方の声がちょっと聞き取りづらくてすみません。大阪のサテライトもあったのに上手く同期出来ず… もう少しやり取りするのか?その手法は?とか詰めておけばよかったです。また、弊社の環境があまり良くないので、マイクとかスピーカーとか増強したいなと考えています。運営に関しては反省点が多かったですが、内容は面白いはずですので、是非ご覧ください。ストリーミングの録画はこちらです。
お礼
良質なコード、マサカリをくださった先生方、当日オフライン、オンラインで参加してくださった皆様、ありがとうございます!
ストップウォッチのネタについては @iseebi さんに助言を頂きました。ありがとうございます!
@ytabuchi 要素としてリスト、スイッチ(ちょっと制御の面倒なコンポーネント)くらいはほしいですね。あとValueConverterどうする?というとこで時間なんか扱うとほどよく面倒になるのでアラーム設定画面なんかを題材にすると良いのではないでしょうか。
— いせ (@iseebi以外は偽物です) (@iseebi) 2015, 11月 19
後、勉強会の後片付けをしてもらった弊社のXXさんとXXさんもありがとう。
ということで、次回 JXUGC は 1月末〜2月初旬の木曜夜か金曜夜に Xamarin での NuGet の使い方や CI との連携についてを題材にして開催します。近々ご案内しますのでご期待ください♪
Xamarin 気になった方は
是非 ダウンロード(直接) / ダウンロード(弊社経由) して触ってみてください。 学習用リソース や JXUG リンクページ に参考資料を纏めてますので併せてどうぞ。
Xamarin の情報が欲しい方はこのブログも購読いただいたりすると嬉しいです。
以上です。