今更MVCとかでAndroidアプリつくってみた（Java）

# はじめに

[これ](https://qiita.com/am10/items/407f82b8e7756e8082a8)のAndroid版(Java)です。

私のAndroidの経験はなんとなく動くやつが作れるレベルです。iOS作ったんでせっかくなんでAndroidも!!という感じで。

Androidあんま知らないので、とりあえずMVCで作ってみました。AndroidのMVCについてざっと調べてみましたがよくわからなかったのでかなりiOSに寄せています。

おそらくこうだろうという感じで作っているので間違っていたらご指摘いただけたら幸いです。

以前作ったiOSのやつ

* [今更MVCとかでiOSアプリつくってみた（Objective-C）](https://qiita.com/am10/items/407f82b8e7756e8082a8)
* [今更MVCとかでiOSアプリつくってみた（Swift）](https://qiita.com/am10/items/6e76ec231ee1251560cc)

# 環境

macOS High Sierra バージョン10.13.2

Android Studio 3.2.1

# つくるもの

あまりに機能がなさすぎると色々な設計でつくっても違いがわかりにくいと思うので今回は下記のようなアプリを作ります。

## アプリ要件

[livedoor天気のWeb API](http://weather.livedoor.com/weather_hacks/webservice)(商用利用不可)を利用した各都道府県の天気を表示するアプリ。

対象はAndroid 5.0以降。

### 機能

４７都道府県を一覧表示し、選択した都道府県の今日、明日、明後日の３日間の天気を表示する

* 都道府県一覧の表示は各地方で絞り込みができる
* 都道府県のお気に入り登録ができる（端末で記憶する）
* 都道府県一覧の表示はお気に入りで絞り込みができる

### 画面構成

都道府県一覧画面と詳細画面の２画面。（スプラッシュ含め３画面）

スプラッシュ画面は無視します。（MVCとかで分離しないので）

#### 都道府県一覧画面

![default](https://user-images.githubusercontent.com/34936885/41820589-06b826d6-780f-11e8-841c-42a95b27b6a7.png)

* ４７都道府県を一覧表示
* 都道府県選択で通信で天気情報を取得し詳細画面に遷移する（エラー時は遷移しない）
* 星マークタップでお気に入り登録削除を行う
* お気に入りのみ表示チェックボックスのチェックでお気に入りのみ表示する
* 地方で絞り込みボタンで下の画像のようなポップを表示する

![default](https://user-images.githubusercontent.com/34936885/41820592-1559e7c4-780f-11e8-9409-bcab0515e897.png)

* チェックの切り替えで一覧表示を絞り込んで表示する

#### 詳細画面

![default](https://user-images.githubusercontent.com/34936885/41820596-22f70d80-780f-11e8-868f-5649566376dc.png)

* 選択した都道府県名を表示する
* 選択した都道府県の今日、明日、明後日の３日間の天気を表示する
* 表示内容は日付、アイコン、天気、最高気温、最低気温の５項目を表示する
* 右上の再読み込みボタンで天気情報を通信で再取得する

# 用語解説

MVCとかで個人で認識の違いが出るのはカタカナ語の意味があいまいなのも１つの原因かと思います。

MVCとか調べていてビジネスロジックって結局なんやねんとよくわからなくなるのでこの記事でいうカタカナ語の意味について書いておきます。（実際の意味とは違うかもしれませんが...）

## ビジネスロジックとは？

[ここ](https://wa3.i-3-i.info/word13666.html)の説明では「そのシステムにおける、システム固有の処理を行う部分」とある。

このアプリでいうと下記が該当

* 各地方での絞り込み
* お気に入りの登録
* お気に入りの絞り込み
* 天気情報の取得

## レイアウトとは？

このアプリでいうと下記が該当

* Viewなどの部品の配置
* 都道府県一覧の表示
* 天気情報の表示

## ユーザアクションとは？

このアプリでいうと下記が該当

* ボタンのタップ
* セルのタップ

# それぞれの設計

つくったものは[ここ](https://github.com/adventam10/AndroidArchitecture)にあげました。

今回つくったものは通信に[Okhttp3](https://github.com/square/okhttp)、JSONデータを扱うクラスの作成に[JSONExport](https://github.com/Ahmed-Ali/JSONExport)を利用しました。

それぞれの設計の私の認識、ファイル数、Activityの行数、つくった感想を書いていきます。

## ほぼActivity

とりあえず何も考えずにほぼActivityでつくったのが[これ](https://github.com/adventam10/AndroidArchitecture/tree/master)

### ファイル数

* javaファイル: 18 
* xmlファイル: 21

### Activityの行数(コメント含む)

* 都道府県一覧画面: 325行
* 詳細画面: 287行

### つくった感想

ファイル数は少なく開発スピードは早い。どのクラスも300行前後でおさまっているのでこのくらいの規模ならこれもありかなと思います。Adapterに処理を書くのでわりとActivityの行数は少なくなった感じがします。

## MVC

プロジェクトは[これ](https://github.com/adventam10/AndroidArchitecture/tree/MVC)

### 認識

![A_MVC](https://user-images.githubusercontent.com/34936885/55681979-9eaaad80-5967-11e9-8fe2-ca4e0f6baa44.png)

#### Model(該当するもの：Object)

* データの保持
* ビジネスロジック
* データ変更をControllerへ通知

#### View(該当するもの：Fragment, View, xml)

* 画面のレイアウト
* ユーザアクションをControllerへ通知

#### Controller(該当するもの：Activity)

* ModelとViewの仲介
* Viewからユーザアクションの通知を受けModelのデータを更新
* Modelからデータの更新通知を受けViewの表示を更新

### ファイル数

* javaファイル: 23 
* xmlファイル: 25

### Activityの行数(コメント含む)

* 都道府県一覧画面: 175行
* 詳細画面: 144行

### つくった感想

とりあえずFragmentをViewとして作りました。ボタンのイベントの取得やら、AdapterにListを渡すのが多少面倒ですがまあスリムになりました。Modelを作ると```onSaveInstanceState```で保存するのが楽になる気がします。PopupWindowの表示処理がActivityの行数を結構増やしているのでここをもう少し分割できれば、もう少しスリムにできるかも。部品が多い画面とか取は```findViewById```をFragmentにまとめれるのでかなりActivityはスッキリするので結構みやすいんじゃないかと思います。

# その他

その他主旨とずれますが気になった点

* strings.xmlは画面ごとに作るべきか？
* styles.xmlは画面ごとに作るべきか？
* colors.xmlは画面ごとに作るべきか？
* layoutのxmlのTextViewのデフォルト文字の表示はstrings.xmlに記載すべきか？（レイアウトを見るためにとりあえず表示する文字）
* メンバ変数にプレフィックスのmつけるのは古い？

# さいごに

iOSの感覚で作ると慣れない部分も結構多かったです。ViewControllerと同じ感覚でActivity使ってたらめっちゃバグりました。ActivityとFragmentてこんな頻繁に死ぬんですね。AdapterにもListを持たせるのが気持ち悪い感じがしますが、これはどうしようもない気がします。

この記事はだれかに意見して欲しいと思って書いたので何かちょっとしたことでも意見をくださるとありがたいです。
俺が思う「最強の設計はこれだ！」というのがあれば、是非上記の仕様でアプリつくってみて下さい。

気が向いたらKotlinでも作ってみようと思います。最近はもうKotlinが主流な気もしますし...