7. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
この図はアプリを作る時によく出てくるコンポーネントよ。
ここではコンポーネントという言葉を、「一塊の機能を実
現するClass群」という意味で使っているわ。(他にいい
言葉無いかな…)
よく使うコンポーネント
外部サービス
データソース
コンポーネント
コンポーネント
コンポーネント
コンポーネント
コンポーネント
コンポーネント
コンポーネント
7
8. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
Modelもコンポーネントの一つよ。まずは、他のコン
ポーネントとModelの違いをはっきりさせることにするよ。
よく使うコンポーネント
8
9. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
まずはプレゼンテーション層から。
9
10. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
Viewは「データを表示」したり「ユーザの操作を受け付
ける」部分ね。Class名に
〜View
となっているやつかな。
ViewというよりWidgetみたいなものだけど。ImageView
とかBuLonとかね。
ボタンやTextbox等
EventをTargetに送る
データを表示する
10
11. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
次は、iOSならViewController、AndroidならAc@vityや
Fragmentと呼ばれる部分ね。iOS的な呼び名で悪いけ
ど、今後VCと呼ぶことにするわ。古典MVCでいうViewと
いうのはこのVCのことだと思うけど、論争になるので略
ユーザの操作で
生成・消滅
ボタン連打などで
頻繁に生成・消滅もあり得る
1画面1+インスタンス
ボタンやTextbox等
EventをTargetに送る
データを表示する
UIの状態制御とModelとの対話
11
12. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
VCの役割は画面の制御。Viewとの対話、画面の状態
制御、Modelとの対話、が主な役割ね。複雑なビジネス
ロジックが入り込みがちなのは世の常だけど、ある程
度経験がある人はそれを意識して回避するわね。
ユーザの操作で
生成・消滅
ボタン連打などで
頻繁に生成・消滅もあり得る
1画面1+インスタンス
ボタンやTextbox等
EventをTargetに送る
データを表示する
UIの状態制御とModelとの対話
フルスタックVCはよく
あるアンチパターン
12
13. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
VCの特性として忘れてはいけないのは、「ユーザの操
作で生成・消滅する」ということよ。それがいつなのか
基本的に予測が付かないわ。これ重要だから覚えてお
いてね。あと、Singletonにするとかやめてね。
ユーザの操作で
生成・消滅
ボタン連打などで
頻繁に生成・消滅もあり得る
1画面1+インスタンス
ボタンやTextbox等
EventをTargetに送る
データを表示する
UIの状態制御とModelとの対話
トキ、安らかに眠れ
13
14. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
次はビジネス層。
14
15. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
まず、ビジネス層はプレゼンテーション層を参照しては
いけないよ。これは絶対のルール。
✕
ダメ、絶対
15
16. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
En@tyは「データそのもの」よ。他のModelやAPIを参照
したり、そういう複雑な操作は一切しないわ。単にList
やMapだったり、DTOやValueObjectみたいなシンプル
なObjectをイメージしてね。
ユーザ入力やデータ
層の結果から生成
データそのもの
List,
Map,
Object
不変ObjectがBeLer
16
17. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
でも例えば「画面の範囲」を表すEn@tyで「面積を計算」
「中央の位置を計算」程度なら良いと思う。でもGlobal
なPropertyを参照したりはしない。さじ加減は難しいけ
どあまり他のClassを参照することはしないかな。
ユーザ入力やデータ
層の結果から生成
データそのもの
List,
Map,
Object
不変ObjectがBeLer
17
18. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
En@tyはアプリケーションの本質となるデータで、フラグ
とか画面・通信状態とかとはまた違います。ユーザが
入力したり、サーバから取得したようなデータね。
ユーザ入力やデータ
層の結果から生成
データそのもの
List,
Map,
Object
不変ObjectがBeLer
18
19. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
En@tyはマルチスレッドの場合などで、不変Objectであ
る方が便利なこともあるけど、そこまで意識しなくても
良いかもしれない。スレッド周りの罠はたくさんあるから
今回は触れないようにします。
ユーザ入力やデータ
層の結果から生成
データそのもの
List,
Map,
Object
不変ObjectがBeLer
スレッドはパンドラの箱
19
20. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
En@tyがSaveとかLoadとかデータ層へのアクセスを提供
するケースもあります。でも、オススメはそういうことは
Modelに任せてしまって、En@tyは単なるデータくらいの
位置づけが良いと思っています。
ユーザ入力やデータ
層の結果から生成
データそのもの
List,
Map,
Object
不変ObjectがBeLer
色々あるからなー
20
21. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
さて、いよいよModel。Modelはデータを取得・提供・計
算・保存するのが主な役割。データを扱う中心的な役
割ね。内部状態も持つよ。Modelは複数存在して各々
取り扱うデータが異なるよ。ここは概ね良いわよね。
ユーザ入力やデータ
層の結果から生成
データそのもの
List,
Map,
Object
不変ObjectがBeLer
データの提供・取得・更新の責任者
機能やデータグループ毎に存在
基本死なない
「通知」で変更を伝える
21
22. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
Modelは、基本Singleton的な非常に長寿命なObject、
とするわ。「基本死なない」ということ。Sta@cなロジック
やHelper的なものは除くけど。これはいつ消滅するか
わからないVCやAPIと大きく違う点になるわ。
ユーザ入力やデータ
層の結果から生成
データそのもの
List,
Map,
Object
不変ObjectがBeLer
データの提供・取得・更新の責任者
機能やデータグループ毎に存在
基本死なない
「通知」で変更を伝える
22
23. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
Modelは、データの更新があれば「通知」で変更を伝え
る、とするよ。「通知」は「Callback的なもの」とは少し意
味合いが違うよ。これは後でまた説明します。ちなみに
ObserverとかNSNo@fica@onは「通知」の実装例だよ。
ユーザ入力やデータ
層の結果から生成
データそのもの
List,
Map,
Object
不変ObjectがBeLer
データの提供・取得・更新の責任者
機能やデータグループ毎に存在
基本死なない
「通知」で変更を伝える
23
24. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
この2点「基本死なない」「通知で変更を伝える」という
ものをModelとした場合、「Modelがない」ことが多い、と
いうのが最初に言っていたことになるわ。
ユーザ入力やデータ
層の結果から生成
データそのもの
List,
Map,
Object
不変ObjectがBeLer
データの提供・取得・更新の責任者
機能やデータグループ毎に存在
基本死なない
「通知」で変更を伝える
24
26. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
「基本死なない」「通知で変更を伝える」という性質が何
故大事なのか、というのは後でまた説明するよ。実は
そんなもの必要ないかもしれないよね。でも、これが無
いから落ちたりグダグダな実装は多いんだよ。
ユーザ入力やデータ
層の結果から生成
データそのもの
List,
Map,
Object
不変ObjectがBeLer
データの提供・取得・更新の責任者
機能やデータグループ毎に存在
基本死なない
「通知」で変更を伝える
後ほど
26
27. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
とりあえず残りのコンポーネントの説明をしておくよ。
ユーザ入力やデータ
層の結果から生成
データそのもの
List,
Map,
Object
不変ObjectがBeLer
データの提供・取得・更新の責任者
機能やデータグループ毎に存在
基本死なない
「通知」で変更を伝える
27
28. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
Model
Locatorは、Modelを保持しておくだけのコンポー
ネント。「Service
Locatorパターン」というのがあるけど、
その名前をちょっと借りたの。適切な名前かはよくわか
らないけど…
ユーザ入力やデータ
層の結果から生成
データそのもの
List,
Map,
Object
不変ObjectがBeLer
データの提供・取得・更新の責任者
機能やデータグループ毎に存在
基本死なない
「通知」で変更を伝える
死なない
Modelは誰かが登録する
自分では登録しない
Modelを返すのが仕事
名前むずい
28
29. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
LocatorはSingletonで「ModelのSeLer/GeLerしかない」
と思って良いよ。Setはアプリの起動処理時にしかるべ
き部分で明示的にModel
Objectを作成してSetするよ。
ユーザ入力やデータ
層の結果から生成
データそのもの
List,
Map,
Object
不変ObjectがBeLer
データの提供・取得・更新の責任者
機能やデータグループ毎に存在
基本死なない
「通知」で変更を伝える
死なない
Modelは誰かが登録する
自分では登録しない
Modelを返すのが仕事
29
30. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
起動時に明示的にSetするメリットはあって「設定(環境
情報)を伴うModelの初期化」「Main
Thread以外だと初
期化できないModelの初期化」が自然に扱えるというと
ころかな。
ユーザ入力やデータ
層の結果から生成
データそのもの
List,
Map,
Object
不変ObjectがBeLer
データの提供・取得・更新の責任者
機能やデータグループ毎に存在
基本死なない
「通知」で変更を伝える
死なない
Modelは誰かが登録する
自分では登録しない
Modelを返すのが仕事
Singletonだと少し辛い
30
31. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
他にも、ModelはSingletonで実装しても良いのだけど
「Singletonだと単体テストでTest
Doubleに置換しにく
い」のを解決するし、「Pluginのような実装が後から
ModelのObjectを置換できる」というメリットもあるよ。
ユーザ入力やデータ
層の結果から生成
データそのもの
List,
Map,
Object
不変ObjectがBeLer
データの提供・取得・更新の責任者
機能やデータグループ毎に存在
基本死なない
「通知」で変更を伝える
死なない
Modelは誰かが登録する
自分では登録しない
Modelを返すのが仕事
挿げ替え簡単
31
32. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
Model
Locatorを使うかどうかは状況次第だけど、さっ
き言った問題で困ったら使うと良いよ。
ユーザ入力やデータ
層の結果から生成
データそのもの
List,
Map,
Object
不変ObjectがBeLer
データの提供・取得・更新の責任者
機能やデータグループ毎に存在
基本死なない
「通知」で変更を伝える
死なない
Modelは誰かが登録する
自分では登録しない
Modelを返すのが仕事
32
33. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
最後にデータ層。
33
34. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
まず、プレゼンテーション層参照することは絶対にダメ。
ビジネス層も参照しないのが原則だけど、「APIの結果
でEn@ty
Objectを返す」のをどう考えるべきか…
密結合
で替えが効かないけど、議論の余地はあるのかも?
✕
ダメ、絶対
?
34
35. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
APIは、外部サービスの通信の仕様を吸収するよ。1リ
クエスト1インスタンスの短命さ、他のAPIを呼び出さな
い単純さ、を原則とすると良いと思うよ。
短命単純
1リクエスト1インスタンス
外部サービスの通信仕様を吸収
APIは他のAPIを使用しない
やっぱり単純は最高だぜ
35
36. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
さっきも触れたけど、APIの結果としてビジネス層の
En@ty
Class
Instanceを返すのをみたことがあります。密
結合になる、というのがデメリットなんだけど、En@tyが
APIと1対1ならありなのかな、と思わなくもない
短命単純
1リクエスト1インスタンス
外部サービスの通信仕様を吸収
APIは他のAPIを使用しない
何か歪だ
36
37. (VC)
ViewController
Fragment
View
View
Model
En@ty
En@ty
En@ty
Model
Locator
Model
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
最後、Local
Data
Accessは、ファイルやDBなどへのアク
セスを提供するよ。同期的な場合と非同期的な場合が
あるかな。ここも色々なケースがありそうだし今回はあ
まり触れないことにします。
短命単純
1リクエスト1インスタンス
外部サービスの通信仕様を吸収
APIは他のAPIを使用しない
ファイル・DBなどへのアクセス
37
53. (VC)
ViewController
Fragment
View
View
Model
Model
Locator
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
そこでModelを使うよ。こんな風になるよ。
生成・所有する
Callback
通知
所有
更新要求
基本死なない
「通知」で変更を伝える
53
55. (VC)
ViewController
Fragment
View
View
Model
Model
Locator
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
まず、VCは無効になる前に「通知の受信を解除」する
ので、前述の「危険と無駄の温床」はなくなるよ。
生成・所有する
Callback
通知
所有
更新要求
基本死なない
「通知」で変更を伝える
既に無効なVC
解除する
帰宅するときは
社用携帯
OFF!
55
56. (VC)
ViewController
Fragment
View
View
Model
Model
Locator
En@ty
En@ty
En@ty
API
API
API
プレゼンテーション層
ビジネス層
データ層
State
Machine
Local
Data
Access
また、ユーザの操作で何度もVCが生成されて、Model
に何度も「更新要求」を出しても、Modelが内部状態を
持って無視するようにできるよ。「既に通信中」「X秒前
に通信したから無視」のようにね。
生成・所有する
Callback
通知
所有
更新要求
基本死なない
「通知」で変更を伝える
状態によって
要求を無視
やり過ごし社員!
56