前回の記事で、
UWP
はPrism
が無いとマゾい
という内容を書きました。
別に反響とかなかったですけど、現在、記事にも書いた通り、Prism
の勉強をしています。
ただ、そう考えると、WPFもやったことがない人にとって、UWPを始めるまでの壁が高いのでは?と、ふと思いました。
というわけで、UWP
やPrism
を使う上で、たぶん前提として知っておいたほうが良い仕組みや、用語について考えてみます。
参考資料は以下の通り。
なお、C#で、UIをXamlで記述する場合を対象にしています。
JavaScript等を利用される場合は、申し訳ありませんがお役に立つ記事ではないと思います…
MVVMパターンについて
元をたどれば、MVCパターン
から派生したものです。
フレームワークレベルで採用しているものとしては、Ruby on Rails
やASP.NET MVC
あたりですかね。
UWP
では、Microsoftが出している単体のフレームワークには、アーキテクチャへの言及はありません。*1
ただ、よっぽど単純なシステムでない限り、MVVM
パターンに則るべきです。*2
MVVM
は、画面をModel
、View
、ViewModel
に分けて開発する手法だよ!
と言っても仕方ないので…もっとざっくり説明してみます。
上の図を説明すると、
- ViewModelは、ViewとModelを仲介する
- 表示すべきデータ等は、Modelが持っている(取ってくる)
- Viewは、ユーザーの入力をViewModelに渡し、また、ViewModelのデータを表示することに専念する
- ViewModelは、ModelのデータをViewが扱いやすい形式にする
- 基本的には、片方向への参照しか持たない
といった感じです。
ただ、そもそもなんでこんなに面倒なことをやるのか?と思われる方もいるかもしれません。
特にWindows Form
しか経験がない、という方とかは特に。
これは、一言で言うなら、「画面に処理を書いたって、なにもいいことがない」からです。
まずは、画面にロジックを書くと、そのロジックを検証するのに画面を動かすしかないです。
テストが自動化できない。
そして、Viewは画面という、すごくざっくりした説明しかしていませんが、Viewはいわゆる「ユーザーインターフェース層」であり、役割はユーザに情報を表示して、ユーザのコマンドを解釈することです。*3
たとえば、画面で手入力できるデータを
ファイルで読み込みたい!
とか
ファイルに書きたい!
とか、はたまた
他のシステムから連携させたい!
等の処理を作る必要が出た場合、表示データの計算等をすべて画面がやっているとどうなるか…
さて、そうなった画面を、今度はモバイルで使えるようにしてみましょう。*4
DI(Dependency Injection:依存性の注入)
いくつかリンクを貼ります。
DIは、要するに「そのクラスが使うものは、外部から渡す」ことを言います。(だから、「注入」という言葉が使われる)
ソースはこんな感じです。
(仮想ケース:項目が追加されたらメールを送る)
//DI未使用 public class BoardNotDI { public void Add(Item item){ //~なにがしかの追加処理 var mailer = new MailSender(); mailer.Send(receiverInfo); } } //DI使用 public class BoardDI { //IMailSenderは、インターフェイス private IMailSender _mailer; public BoardDI(IMailSender mailer) { _mailer = mailer; } public void Add(Item item){ //~なにがしかの追加処理 _mailer.Send(receiverInfo); } }
『C#実践開発手法』では、クラス内で独自にnew
でインスタンス生成するのを推奨していません。理由は以下のような感じです。
そのクラスに依存するからやめろ
単体テスト(自動テスト)できなくなるからやめろ
ソース見ないと何に依存しているか分からなくなるからやめろ
サービスの依存関係に依存するからやめろ
他のサービスを柔軟に利用できなくなるからやめろ
『レガシーコード改善ガイド』には、依存性に関して、以下の記述があります。この表現大好きです。
メソッドに悪い副作用(データベースの更新、巡航ミサイルの発射など)があり、テストハーネスで実行することが不可能である
「巡行ミサイルの発射 = メールの送信」です。
単にソースコードのテストしたいだけなのに、毎回実際のメールが送られたり、ミサイルが飛んでいったりしたら、たまったものではありません。
インターフェイスを渡すと、それをテスト用の実装に入れ替えることで、そのクラスが単体テスト可能になります。
とまあ、たったこれだけのことです。
DIコンテナ?その説明はまたいずれ…
非同期処理
UWP
では、ファイルアクセス等、時間がかかる可能性がある処理は、ほとんど非同期用のライブラリばかり用意されています。*6
そういうわけで、async, await
やTask
は、当たり前のように出てきます。
これに関しては、以下の記事が秀逸だと思います。見てください。というか、ネットで探すといっぱい出てきます。
Task
のWait
はしない、と書かれていました。そうだね。await
あるもんね。
非同期処理がない言語や、スレッドを直接扱う方法しかない言語を知っている身ですので、本当にありがたい機能です。*7
ちなみに、匿名メソッドにもasyncは書けます。
最後に
まずは最初に、というところでは、上のようなものでしょうか。
思いついたことがあったら、また記事にします。
余談
そもそも、UWP
の記事を書き始めたときの記事が、ありがたいことに、なぜかアクセスが伸びました。
Googleでキーワード検索したら、なぜか一番上に出てました。なるほど。
偶然です。
今後も、誰かに何か役に立つ記事を書けたらいいな、と思った所存でございます。
今回の記事、長すぎ…