Android版Conobieの改善 〜モダンな仕組みを入れて〜


『[LITALICO Engineers Advent Calendar 2017](https://qiita.com/advent-calendar/2017/litalico)』23日目の記事となります。

[株式会社LITALICO](http://litalico.co.jp/)でAndroidアプリのアドバイザーをしている @nissiy です。LITALICOでは主に[Android版Conobie](https://play.google.com/store/apps/details?id=jp.conobie.conobieandroid&hl=ja)の開発全般のお手伝いをしています。
前々職の上司であり、LITALICOのCTOである @takish さんから __今年も書いてくれ__ と指名されたため23日目の記事を書くことになりました。
昨年は諸事情により[裏アカウント](https://qiita.com/higassiy)から参加させていただきましたが、今年は表アカウントからの参加です(∩´∀｀)∩ﾜｰｲ

# はじめに
[昨年の記事](https://qiita.com/higassiy/items/98b62364938289e112c1)でも書きましたが、LITALICOにおける私のミッションは『<b>アプリを良いものにする</b>』と『<b>LITALICOのAndroid開発レベルを引き上げる</b>』の2点です。
今年もAndroid界隈では様々な発表やアップデートがありましたが、それら新しい血を積極的にアプリに取り入れることで、アプリはより良いものになり、またチームの開発レベルを向上させることができます。

今回は、今年新しくAndroid版Conobieに取り入れた仕組み3点を紹介すると伴に、それらを取り入れる際の開発ルールについてまとめてみました。どれも実際に現場で使っている内容なので少しでも参考にしていただけたら嬉しいです。

# ConstraintLayout
Google I/O 2016で発表された[ConstraintLayout](https://developer.android.com/training/constraint-layout/index.html)ですが、今年の頭に1.0がリリースされてやっと使えるレベルになりました。
RelativeLayoutと比べてパフォーマンスが __約40%__ 優れているという[記事](https://android-developers.googleblog.com/2017/08/understanding-performance-benefits-of.html?m=1)を見かけたことをきっかけに、Conobie内で使用しているFrameLayout、RelativeLayout、LinearLayoutをConstraintLayoutに置き換えることを決めました。

学習コストは少し高めでしたが、Layout Editorを使わずに __手書きでXMLを記述してConstraintLayout使う__ 道を選択しています。
Layout Editorで作ってしまうと、人間が微調整できないXMLができあがり細かいデザイン調整を行うのが困難になります。また、ConstraintLayoutは意外に手書きでもしっかり書けるようになっているため、手書きConstraintLayoutはありな選択だと思います。これまでずっと手書きでXMLを書いてきたのに今さらGUIエディタを使う気になれなかった人にオススメです。

手書きConstraintLayoutの学習は、仕事仲間でもある @nakker1218 が書いた記事を読んで、ひたすらレイアウトを実装することで身につけました。

https://qiita.com/nakker1218/items/0faa8c1ab504cc4cedea

# Android Architecture Components
今年のGoogle I/Oで新しく追加された[Android Architecture Components](https://developer.android.com/topic/libraries/architecture/index.html)も取り入れました。現在はstableになっていますが、alphaのときから思い切って使っていました。
主に[LiveData](https://developer.android.com/topic/libraries/architecture/livedata.html)を使いたかっただけなので、データ永続化のLibraryである[Room](https://developer.android.com/training/data-storage/room/index.html)に関しては現状使用しておりません。

LiveDataは仕組み自体が[Lifecycle](https://developer.android.com/reference/android/arch/lifecycle/Lifecycle.html)に紐付いているため、データの取得や更新の際にActivityのライフサイクルを過剰に意識しなくて良くなります。取り入れてみて各画面のActivityが非常にスッキリした印象を受けました。
チームでRxJavaを使ってこの部分の実装していると、経験上どうしても __dispose__ し忘れが見受けられていました。Architecture Componentsを使って環境さえ整えてしまえば、ライフサイクルによるリークやクラッシュの原因になり得るものを意識する必要がなくなるため、View実装時に画面実装に集中することができるようになりました。
開発者が全員Android開発の経験豊富なメンバーとは限らないので、このような仕組みがGoogle公式であると非常に助かります。
なぜ今までなかったのか。


以下、一部を抜粋したコードになります。

```SettingsActivity.kt
// viewModelFactoryは以下のURLのコードを参考にして作ったものをDaggerでInjectしたもの
// https://github.com/googlesamples/android-architecture-components/blob/master/GithubBrowserSample/app/src/main/java/com/android/example/github/viewmodel/GithubViewModelFactory.java
viewModel = ViewModelProviders.of(this, viewModelFactory).get(SettingsViewModel::class.java)
viewModel.user.observe(this, Observer {
    it ?: return@Observer
    // UIの更新
})

// 誕生日をviewModel.onUpdateUserBirthdayに渡すことでサーバー側とUI側の両方で更新が行われる
```

```SettingsViewModel.kt
override val user: MutableLiveData<User> = MutableLiveData()

override fun onCleared() {
    // 通信処理を行った場合のdisposeはここで行う
    disposable.clear()
    super.onCleared()
}

fun onUpdateUserBirthday(birthday: String) {
    useCase.updateUser(birthday)
        .doOnSubscribe { disposable.add(it) }
        .subscribe({ user.postValue(it) }, { it.printStackTrace() })
}
```

# Kotlin
3点目に取り入れたものは、今年のGoogle I/OでAndroidアプリ開発言語に正式に採用することが発表され、大ブレークを果たしたKotlinです。Conobieも徐々にKotlinへの移行が進んでおります。

そんなKotlinですが、Javaと比べてかなり自由度の高い書き方ができるため、チームで使うためにコーディング規約を設けました。
コーディング規約は[スマートテック・ベンチャーズさんが書かれていたKotlinコーディング規約](https://github.com/SmartTechVentures/kotlin-style-guide)をベースに、いくつか細かいローカルルールを加えたものになります。
今のところはそれで上手く回っていますが、何か不都合が出てきたらアップデートするなり、独自でゼロから作るなりしていきたいと考えています。

コメントについては[KDoc形式](https://kotlinlang.org/docs/reference/kotlin-doc.html)で書くようにしています。と言っても、BlockTagが増えていたり、Markdownが書けるようになっていたりするだけで、大きくJavaDoc形式と変わりませんが。

あとはクラス内での定義順も以下のように定めました。几帳面なメンバーが多く苦にならないのであれば、可読性や保守性が上がるのでオススメです。
ただしチームを選ぶので強くはオススメしません。私も会社やメンバーをみて薦めるか決めています。

```
class Person {
    // publicの変数（val）
    // publicの変数（var）
    // publicの変数（var lateinit）
    // publicの変数（＠Inject）

    // privateの変数（val）
    // privateの変数（var）
    // privateの変数（var lateinit）

    // companion object

    // constructor

    // init

    // overrideメソッド

    // open publicメソッド

    // publicメソッド

    // open protectedメソッド

    // protectedメソッド

    // privateメソッド

    // privateメソッド

    // Interface

    // Extensions

    // Dataクラス

    // Nestedクラス

    // Innerクラス

    // Enumクラス
}
```

# さいごに
今回はAndroid版Conobieに、以下の3点を取り入れた話と、それに伴う開発ルールを簡単に紹介しました。

- ConstraintLayout
- Android Architecture Components
- Kotlin

すべてGoogle公式のメジャーな仕組みや言語なので既に導入されている方も多いと思いますが、まだ導入されていないチームや会社はぜひとも検討してみてください。

徐々にLITALICOのAndroid開発力が上がっていると感じているので、来年はもっとチャレンジングなことに挑戦したいですね。

明日は @kamesennin さんが何か面白いことを書いてくださるそうです。お楽しみに！