application_architecture_of_android

第8回 アンドロイド勉強会
アンドロイドとMVCアーキテクチャ
1
自己紹介
 名前
 藤井大助(ふじいたいすけ)
 所属
 豆蔵Android同好会。
 仕事
 業務アプリケーションのアーキテクチャ構築や、開
発支援など作業が中心。
 仕事っぷりはいたってまじめ。
2
はじめに
 本セッションでは、「MVC」という切り口で、ア
ンドロイドのアプリケーションアーキテクチャ
を考えたいと思います。
 MVCアーキテクチャはもはや枯れきったとい
うか、UIを伴うアプリケーションを開発する上
での王道と言えるでしょう。それだけに、MVC
をちゃんと意識してアプリケーションを開発す
ることはアンドロイドにとっても大切だというこ
とを伝えたいのです。
3
目次
 MVCアーキテクチャとは何か
 MVCってなぁに?というのを改めて勉強します。
 MVCとMVC2の違い
 Smalltalk MVCとJ2EEで有名になったMVC2の違いに
ついて勉強します。
 MVCアーキテクチャの実践
 MVCアーキテクチャを採用したサンプルプログラムを
題材に、Modelの再利用の切り口で勉強します。
 ローカルマッシュアップの実践
 マッシュアップ容易性が高いアプリの作り方を提案し
ます。
 まとめ
4
MVCアーキテクチャとは何か
5
MVCアーキテクチャとは
 ユーザとの入出力とロジックを分離するアー
キテクチャパターンのこと。
 Model
 ロジックをカプセル化したもの。
 Modelは再利用できるように作る。
 View
 Modelから画面に必要な情報を取得し、ユーザに画
面を表示する役割。
 Controller
 ユーザからの入力を受け付け、適切なModelに処理
を委譲する役割。
6
補足:アーキテクチャパターンとは
 デザインパターン(Wikipediaより引用)
 ソフトウェア開発におけるデザインパターン(また
は設計パターン、英: design pattern)とは、過去の
ソフトウェア設計者が発見し編み出した設計ノウ
ハウを蓄積し、名前をつけ、再利用しやすいよう
に特定の規約に従ってカタログ化したものである。
 アーキテクチャパターンとは、ソフトウェア
アーキテクチャ設計の優れたノウハウをパ
ターン化したもの。(と考える)
7
早速ですが、こんな機能があるとし
ます。
登録画面
照会画面
身長
170
身長:170cm
体重
75
体重:75kg
登録(r)
 これを、MVCアーキテクチャにマッピングする
と・・・
8
MVCアーキテクチャ
身長と体重が更新され
たことを通知する。
完了画面を表示する。
6
4
View
(イベント通知)
3
5
Model
身長と体重を取得する。
2
身長と体重を登録する。
1
登録画面で、身長、体重を入力し
てから、登録ボタンを押下する。
Controller
身長、体重を渡して、登録を
お願いする。
9
MVCアーキテクチャのポイント
 Modelを再利用しやすい。
 ControllerとViewに依存しないため、自然とModelが独立する。
 Modelを中心にした設計、実装がしやすい。
 OO的なアプローチと相性がいい。
 UIの変更に強い。
 UIのロジックはViewとControllerに閉じるので、Modelにまで影響
が及ぶことが少ない。
 UIに閉じた変更であれば、Modelに影響しないということ。
 UIの表示項目が増えたとはかさすがに無理。
 ViewとControllerを一緒と考えてもいい。
 キッチリ分けたくなるが、あまりメリットがない。
 Viewは出力、Controllerは入力ということだけ意識しておけばよ
いと思う。
10
MVCとMVC2の違い
11
Webアプリケーション開発がメインの
方々のために
 先ほど説明したMVCは、いわゆるSmallTalk
MVCと言われるもので、J2EEで有名なMVC2
とは少し毛色が違います。
 しかし、Webアプリケーション開発がメインの
方々には、このMVC2アーキテクチャの方が
有名ではないでしょうか。
 そこで、MVCとMVC2の違いを理解しておい
た方がよいと思いました。
12
SmallTalk MVCとJ2EE MVC2の違い
 MVC2の場合、Modelの状態が変化したことは、
それを呼び出したControllerが知っている。
 Modelを更新したControllerしか、Modelの状態が変化
したことを知らないので、複数のControllerからModel
が更新されるような場合や、複数のViewが同じModel
を参照している場合には不適切である。
 しかし、Webアプリケーションの場合、HTTPリクエスト
毎にControllerやModel、Viewを生成することが一般
的なので、上記のような複数ControllerがModelを更新
したり、複数のViewが同じModelを参照したりすること
はない。
13
MVC2の特徴
MVC2の場合は、次の
ようなマッピングになる。
View; JSP
Controller: Servlet
Model: JvaBeans
2.Model取得
:View
:Controller
1.Model更新
:Model
他のControllerで変更
したことは、教えてあ
げないとわからない。
:View
4.Model取得
3.Model更新
:Controller
14
MVCアーキテクチャの実践
15
サンプルアプリケーション
 昨今の健康ブームをうけて、身体情報からさ
まざまな診断を行ってくれるアプリをつくりま
す。
 身長と体重の登録だけができる。
 BMI値を計算するできる
 ひとまず、上記の機能を実装してみました。
16
画面遷移
 主な機能
 1.身長と体重を登録する。
 2.登録した情報から肥満度を診断する。
1.
身体情報
登録
身体情報
照会
メニュー
肥満度
診断
2.
17
1.身長と体重を登録する。
 まずは、この機能に焦点をあてて説明します。
登録画面
照会画面
身長
170
身長:170cm
体重
75
体重:75kg
登録(r)
18
登場する主なクラスたち
View または、Controllerの役割
Modelの役割
cla s s 身長 と 体重を 登録す る 。
com.ma mez ou.a nd roid .hea lt h.a ct iv it ies
com.ma mez ou.a nd roid .hea lt h.mod els
Hea lt h
Reg is t ra t ionAct iv it y
Hea lt hInfoAct iv it y
+
-
height: double
weight: double
+
+
+
+
+
getInstance() : Health
getHeight() : double
getWeight() : double
isMetabo() : boolean
update(double, double) : void
<<interface>>
Hea lt h.OnUpda t edLis t ener
onUpdated(Health) : void
+
onUpdated(Health) : void
19
コードを見ながら説明、説明・・・
 ポイント
 MVCのそれぞれは、どこにマッピングするのか。
 Modelの変更を通知する仕掛け。
 いわゆる、GoFのオブザーババターン。
 Modelは同じインスタンスを使う。
 今回は、シングルトンで対応した。
 オブザーバ(HealthInfoActivity)のシンプルな実装に注目。
 Modelの状態がいつ変更されるかについては考えなくて良い。
 Modelの状態が変化したときに呼び出されるメソッドの実装。(イ
ベントリスナ)
 イベントリスナが呼び出されたときに自身の画面を更新する。
 もし、Modelをポーリングすると、Modelの何が変更になったとき
に状態の変化とするのかという判断がActivity側に依存してし
まう。
20
2.登録した情報から肥満度を診断
する。
 次はこの機能に焦点をあてて説明します。
メニュー画面
肥満度診断(d)
診断画面
あなたは、
セーフです。
21
登場する主なクラスたち
View または、Controllerの役割
Modelの役割
cla s s 肥満度 を 診断す る 。
com.ma mez ou.a nd roid .hea lt h.a ct iv it ies
com.ma mez ou.a nd roid .hea lt h.mod els
Hea lt h
Met a b oDia g nos t ics Act iv it y
+
onUpdated(Health) : void
-
height: double
weight: double
+
+
+
+
+
getInstance() : Health
getHeight() : double
getWeight() : double
isMetabo() : boolean
update(double, double) : void
<<interface>>
Hea lt hInfoAct iv it y
Hea lt h.OnUpda t edLis t ener
+
onUpdated(Health) : void
+
onUpdated(Health) : void
22
コードを見ながら説明、説明・・・
 ポイント
 オブザーバの実装はシンプル
 どう見せるかはというロジックはActivityの責務となる。
 複数のActivityでModelを共有。
 Modelを変更するだけで、複数のActivityが更新されていること
を確認する。
 Modelを主体として考えるということ。
 Modelが変更したときにActivity(UI)も変更するのが、わかりや
すくてシンプルな考え方。
 Activity(UI)を主体に考えると、Modelから情報を取得するタイミ
ングがずれたりするので、わかりにくくなることが多い。
 もし、ポーリングのような実装だったら、Activityが増えるほど悲
惨な状況になる。
 つまり、Modelの変更を検知するタイミングが、Activityの実装
に依存する。
23
ローカルマッシュアップの実践
24
All applications are created equal.
 アンドロイド上のすべてのアプリケーションは等
価なものとして開発される。
 ユーザが作ったアプリとビルトインアプリとの違いはな
いというように、利用する側、利用される側の垣根が
ないということだと思う。
 逆にいうと、ユーザが作ったアプリも利用される側に
立つこともちゃんと意識して開発すべきなのでは?
 つまり、アプリケーションを疎結合にすることで独
立性を向上させ、お互いが協調しあえる関係を
築くことが重要なのではないか。
 ここでは、既存アプリケーションを利用して、新しいア
プリケーションを作ることを「ローカルマッシュアップ」と
呼びます。
25
因みに、これからの話はMVCの域を
少し脱します。
 ここではローカルマッシュアップについて考え
ます。
 MVCアーキテクチャはアプリケーションに閉じたも
のですが、ローカルマッシュアップを実現しやすい
アプリケーションを開発するためのヒントがあるよ
うに思います。
 多少の無理矢理感はスルーしてくださいませ(汗)
26
ローカルマッシュアップとMVCの関係
Intent通知
application
VC
M
application
VC
VC
M
application
VC
VC
M
VC
Intent通知
27
サンプルアプリケーション
Intent通知
application
これは、MVCで説明
したものをそのまま
使います。
VC
BMI値を計算するこ
M
とだけを行うアプリ
VC
application
VC
身長と体重だけを
管理すうアプリM
application
VC
VC
M
VC
Intent通知
28
ローカルマッシュアップを実現するた
めのポイント
 他のアプリケーションから参照されるインタ
フェースとしてServiceを使う。
 Serviceとは、android.app.Serviceのこと。
 他のアプリケーションにイベント通知する仕
組みは、Intentのブロードキャストを使う。
 Intentとは、android.content.Intentのこと。
 Intentを受け取るイベントハンドラは、
IntentReceiverを使う。
 IntentReceiverは、android.content.IntentReceiver
のこと。
29
利用される側のアプリケーション
~コードを見ながら説明、説明・・・~
 Serviceを追加。
application
VC
M
VC
Serv
ice
 aidlの定義
 Serviceの実装
 Modelの状態変更に合わせて
Intentをブロードキャストする。
 Intentに変更内容を詰めて送信す
る。
 Serviceの公開
 AndroidManifest.xml
 「android:process=“:remote”」する
とModelが共有できなくなる。
30
利用する側のアプリケーション
~コードを見ながら説明、説明・・・~

application
IntentReceiverを追加。



VC
VC
IntentReceiverをActivityに登録。

M

利用される側でブロードキャストされるIntentを
知っておく必要あり。
直接Activityではなく、Modelを更新する。
本当は、AndoroidManifest.xmlでやりたかったけど、
時間がなかったのでActivityで明示的に登録した。
ActivityからServiceを活性化。

利用される側のアプリにあるServiceをスタートさ
せる。
 ひょっとすると動いてないかもしれないから。
Intent
Receiver

ActivityからServiceに接続&呼び出し。

同じaidlの定義をコピー?する。
 将来的には、Webで公開されているaidlを参照して、
Serviceインタフェースを生成するとかかも。
31
最終的には、こんな感じになる。
application
application
VC
M
VC
VC
M
Intent
Receiver
Intent通知
VC
application
Servi
ce
VC
M
VC
Intent
Receiver
Intent通知
32
MVC的なローカルマッシュアップのま
とめ
 利用される側のアプリケーションは、MVCのModelと
よく似た責務を持つ。
 イベント通知の代わりにIntentのブロードキャスト。
 Serviceはできるだけ薄い役割として、他のアプリケーション
からのインタフェースとしての責務を全うさせる。
 あくまでサービスインタフェースですね。
 利用する側のアプリケーションは、MVCのVCとよく
似た責務を持つ。
 イベントリスナの代わりに、IntentReceiverを使う。
 以上で、MVCアーキテクチャに基づいて考えること
で、アプリケーション内、外問わず設計方針の統一
か可能となる。→「わかりやすい設計」につながる。
33
全体のまとめ
34
無理矢理まとめます。
 MVCアーキテクチャを意識するということは、アプリケーションの
本質を見極めることに似ている。


Model主体、Activity(UI)主体の話とか
Modelをどのように設計すればよいかとか
 MVCアーキテクチャはUIを持つアプリケーションに適用できるの
で、例外なくアンドロイドにもマッチする。
 MVCアーキテクチャを採用することで、ローカルマッシュアップな
アプリケーションにも柔軟に対応しやすい。
 だから、MVCを意識してアンドロイドアプリケーションを開発する
ことにはすごく意味があると思います。


ただ、実機が出てないのでパフォーマンスうんぬんはちょっと置いてます。
当たり前ですが、アーキテクチャの決定はトレードオフが必要になります。
何を優先すべきかしっかり考えることが一番重要です。
35
以上で終わりです。
 ご静聴、どうもありがとうございました!
 ご質問など、ございましたらお気軽にどうぞ。
36
おまけ
37
Serviceを呼び出す頻度について
 Webサービスや、RMIなどのリモート呼び出しは
コストが高いことを前提に考えるのが普通です。
 アンドロイドのServiceは、宛先がリモートがロー
カルかを意識しなくて良いように設計されている
ため、基本方針はリモート呼び出しを想定して設
計するのが望ましい。
 J2EEのビジネスデリゲートパターンのように、で
きるだけ粒度の粗いメソッドをServiceに用意して
おくことがよいと考えます。
 Modelのメソッドよりも粒度があらいということ。
38