2017/10/02 CA.apk #4 資料
運用3年のタップル誕生でJavaからKotlin移行した話2017/10/02 CA.apk #41向中野 亘mukky620
View Slide
● 向中野 亘 (むっきー)● ServerSide Engineer↓Android Engineer2自己紹介
1. JavaからKotlinへの移行理由2. 移行の前にチーム内で行なった事3. 移行で悩み・苦労した点4. まとめ3Agenda
なぜJavaからKotlinに移行??4
1. Android開発言語としての正式言語サポート2. モダンな言語仕様3. Javaとの互換性・相互運用性4. 社内のプロダクトでの開発事例・移行の兆し5. アーキテクチャ改善と合わせて6. Javaエンジニアなら習得コスト軽5移行理由
Kotlinが書きたいというモチベーション!6
まず、移行始める前に行なった事7
● 内容○ Kotlin Koans(全42問)を4週くらいに分けて各自解いてくる。(https://try.kotlinlang.org)○ 当日答え合わせして経験者からの補足と別解、プロダクトでの実践的な事例等々の解説をもらう。8週1でのKotlin勉強会の開催
9
10勉強会の良かった点● 自習でつまづいたところを直接聞く事で体系的に学べるので理解が早い。○ プロダクト内での事例を交えたりするのが良い。● ただ話を聞くより自分なりに考えて問題を解いてくるという事が身になる。
11勉強会の悪かった点● 問題文が全て英語なので読み取りづらい部分があった。○ 完全に自分の英語力の問題…
12その他● Kotlin入門までの助走読本(https://drive.google.com/file/d/0Bylpznm149-gTGRjOFRkWm9PODg/view)● Kotlin Blog(https://blog.jetbrains.com/kotlin/)● Kotlinアドベントカレンダー● FRESH!のソースを参考に。
あとはもう書いて覚えようという感じでKotlin移行始めました!13
● チームメンバー4人(経験者1人、未経験3人)○ 経験者はチームに1人は必要だと思う● 施策開発は止められないのでKotlin移行は平行で行う● プロダクトへすぐ導入○ ユーザー影響少なそうな画面(Activity/Fragment)から移行14タップルでのKotlin移行の進め方
● レビュアーアサインについては経験者1人は必須で3人で見る。○ 経験者は基本的にKotlinらしい書き方という面に特化してレビューしてもらう。○ 仕様面のレビューに関しては経験者以外の他のメンバーで見る。15タップルでのKotlin移行の進め方
この体制で最初のうちはガンガン進めていたのですが…16
進めてるうちに悩んだり・苦労した事がちらほら…17
なので今回はそのあたりを抜粋して紹介したいと思います18
悩み・苦労した点19
施策開発と平行で進めるの辛い…
● 施策開発優先なのでKotlin移行だけの専任ラインは作れず、途中から思うように進捗が芳しくない感じに…● Kotlin化のプルリクをmasterマージしたけど、施策開発のみリリースしたいためrevertやタグ切り戻し発生…● 施策開発のプルリク優先しているため、Kotlin化のプルリクが溜まり始める…21施策開発と平行で進める
NonNullかNullableか分からなくて辛い…
● 昔のJavaソースに特に多いがNonNull、Nullableアノテーションついてない…● 正しいAPI仕様書がなく、APIのレスポンスパラメータが必ず入ってくるものなのかどうかが分からなくて辛い…○ ちなみにparserはGson使っている23NonNullかNullableかが分からない
タップルの仕組み24APIレスポンス周りなぜ辛いのか?Entity(レスポンスを格納するObject)Dto(表示等で使いやすいようにEntityをConvertしたObject)ServerAPI通信Converter(Dtoへの変換処理)
タップルの仕組み25APIレスポンス周りなぜ辛いのか?Entity(レスポンスを格納するObject)Dto(表示等で使いやすいようにEntityをConvertしたObject)ServerAPI通信Converter(Dtoへの変換処理)Gsonでparse
26Entity(Javaソース)例えばアイテムによってはcaptionが返却されないとすると。caption以外→NonNullcaption → Nullable
タップルの仕組み27APIレスポンス周りなぜ辛いのか?Entity(レスポンスを格納するObject)Dto(表示等で使いやすいようにEntityをConvertしたObject)ServerAPI通信Converter(Dtoへの変換処理)EntityをDtoに変換する処理
28ConvertershopItemResponseはJavaソースの呼び出しなのでプラットフォーム型になるが、caption以外はAPIの仕様上NonNullが保証されているとする。
29Dtoこの場合、Dto側は全てNonNullで定義してしまっているので、例えばcaptionが返却されなかった場合にNonNull定義のcaptionにnullが代入出来てしまい、Null安全ではなくなる
タップルの仕組み30APIレスポンス周りなぜ辛いのか?Entity(レスポンスを格納するObject)Dto(表示等で使いやすいようにEntityをConvertしたObject)ServerAPI通信Converter(Dtoへの変換処理)変換後のDtoのフィールドをNonNull定義にすべきかNullable定義にすべきか分からない
そんなのサーバーの人に確認してもらえば良いんでない??31
● Kotlin化のためにサーバーの人にAPI毎のレスポンスの確認取ってもらうの結構コスト…○ サーバーはNode.jsでレスポンスはjson● API数はAndroidで使ってるだけでも約130〜140くらいある…ヒィ。。→ 絶賛サーバ側でAPI仕様書作るためのツール開発中!32コストが…
書き方の自由度が高過ぎて悩む…(ときがある)
● この時はこの書き方がベストだという事がないため慣れないうちは迷う事が多々ある…○ 特にJava移行組は余計に迷う○ もっと良い書き方があるんじゃないかと迷いだして時間が経つ…○ スコープ関数の使い分けとか自分的に特に迷う…34書き方の自由度が高い
35スコープ関数
36スコープ関数apply, run, let, also, with
ちなみに皆さんちゃんと使い分けられてますか??37
自分はスコープ関数の使い分けが中々理解できず、経験者の方から説明していただいた使い分けイメージをパクって参考にして使い分けています。※あくまでもイメージなので全て当てはまるわけではないと思います!38スコープ関数の使い分け
● 意味合い的に適用する場合に使用● よくcreateInstanceとかで使用するイメージ● 基本的に(自身)戻り値を使用する● インスタンスのプロパティが変化する時とかに使用39apply
● 同じ戻り値である必要がないまたは同じ戻り値を変えたい時に使用● this.func() ○● func(this) X的なイメージで使用している。40run
● 同じ戻り値である必要がないまたは同じ戻り値を変えたい時に使用● Nullableに対してよく使用● func(it) ○● it.func() X的なイメージで使用している。41let
● 自身を返却する● itを使うけどitには変化を与えない● 基本的に戻り値を使用※正直まだ1度も使えてない…42also
最終的にはたろーさんの下記サイト見てます。https://qiita.com/ngsw_taro/items/d29e3080d9fc8a38691e43スコープ関数の使い分け
うーん…使いこなしたい。。44
45まとめ
● JavaからKotlin移行は当初思っていたより大変だった。→ 特に運用年数長いほど負債が多いからより大変。● 施策開発と平行で進めるのは難しい。→ 施策と施策の谷間で地道にコツコツやるか、もしくは出来るのであれば施策開発止めて集中コミットするのが良いのかもしれない。46まとめ
● NonNull、Nullableアノテーション大事!→ convert前に明示的にしっかりつけるべき。● 書き方の自由度が高いので慣れないうちは迷いがち。→ 都度相談・議論しながらチーム内で共通認識を持つ事が大事。コード規約をしっかり定めるのが良い。(スコープ関数も使いこなしたいですね)47まとめ
この経験を活かしてより良いKotlin移行を模索しながら引き続き進めていきます!48
ご静聴ありがとうございました!49