2018年モバイルファクトリーアドベントカレンダー 12/3担当の id:yashims85 です。 前日は id:odan3240 さんの NuxtMeetUp#5 でnuxt-i18nを用いたwebサイトの多言語化について話してきました でした。
まえがき
2018年今日において、クロスプラットフォーム(以降: X-PF)界隈を改めて見てみると、大手各社がそれぞれアーキテクチャを提供をしており、X-PF戦国時代の様を呈しています。 今回はその中でもKotlin/Native(以降: K/N)とFlutterに絞って比較を行いたいと思います。
確認した環境はそれぞれ2018/12/03時点で最新である以下です。
- Kotlin - 1.3.10 (Kotlin/Native Beta)
- Flutter - v0.11.13-beta
実のところ、両X-PFを触る前は何を書こうか迷っていたのですが、K/N、Flutter、及び他のX-PFを触ってみて感じるのは、どのX-PFにも長短があり現時点での銀の弾丸は無いという事です。 そこで、今回はKotlin/NativeとFlutterの比較を行いそれぞれの長短を把握してもらうことで、自分の状況にあったX-PF選びの参考にしてもらえたらと思います。
今回やらないこと
- Getting Started
- 各PFのGetting Startedが引っかかる部分も無かったので、そのとおりにやったら良いと思います
- 最強のX-PFはコレだ!
X-PFについて
Android/iOSの両モバイルOSの登場以来、古今東西様々なX-PFが生まれては消えていきましたが、現在X-PF界隈に置いては、大手デベロッパーを背後に持つX-PFに淘汰されて来ています。
一例をあげてみましょう。
X-PF | 主開発社 | 言語 | 特徴 |
---|---|---|---|
Xamarin | Microsoft | C# | X-PFとしての歴史、VisualStudioを使用した快適な開発環境、各PFそれぞれのUI実装 |
Unity | Unity | C# | リッチコンテンツに強み、共通UI、独自ライフサイクル、ゲームエンジンベース |
ReactNative | JS | Reactと同じノリで作れる、共通UI | |
Kotlin/Native | JetBrains | Kotlin | AndroidStudioをIDEとして使用できる、各PFそれぞれのUI実装、まだBeta |
Flutter | Dart | Google系サービスならポン付け実装できる、独自ライフサイクル、基本は共通UI、まだBeta |
この中でもKotlin/NativeとFlutterはAndroidエンジニアにとって馴染みの深い2社が開発していることもあり、 気になっている方も多いんではないでしょうか?
Kotlin/Native
現在のAndroidの標準開発言語であるKotlinを開発したJetBrains社が主導で開発を進めています。Kotlin 1.3からBeta機能としてKotlin/Nativeが提供されています。 K/NはKotlinという言語に対してX-PF機能を付加するアプローチをとっています。
K/Nは以下のような特徴があります。
- 宣言を実装を分けることができる言語仕様と各PF用のビルドシステムによって実現
- AndroidではJVM言語として、DalvikVM、ART上で実行される
- iOSではLLVMで機械語にコンパイルされ、iosのframeworkとして吐かれる
- frameworkにはK/Nコードのシンボルがヘッダファイルとして包含されているため、Swift側からもK/Nのコードを参照できる
- UIの共通化機能は提供されておらず、それぞれのPFで実装する必要がある
Flutter
Googleが主導で開発を進めています。こちらもBetaですが、Betaとは思えないほど機能やドキュメントが充実しています。 Flutterは純粋に開発環境の共通化を目的として作るアプローチをとっています。
Flutterは以下のような特徴があります。
- Dartは滅びぬ!何度でも蘇るさ!
- Android/iOSともに機械語にコンパイルし実行する
- UIパーツが多数提供されており、独自性の強いデザインを押し出さなければ爆速開発が見込める
- Reactに影響を受けたアーキテクチャ設計
- 各OSの機能とは遠い
開発環境
Kotlin/Native | Flutter |
---|---|
Android Studio / IntelliJ IDEA | Android Studio / IntelliJ IDEA, VSCode |
当然といえば当然ですが、どちらもAndroid Studioがそのまま使えるのが面白いですね。
どちらもBetaなので細かくは言及しませんが、現段階ではK/Nはディレクトリを作ったりbuild.gradleをいじったりと結構手作業で環境を構築する必要があり、若干の敷居の高さを感じます。 対してFlutterは、ASにPluginを導入するだけでFlutter環境をセットアップできるので、拍子抜けするほど楽ちんです。
またX-PF開発ではXcodeを触る時間をいかに少なくするかが鍵だと私は考えています。 この点においてもFlutterは現段階で一歩リードしており、Signing周りをポチポチするだけです。 対してK/NはBuildPiplineに手を加える必要があり、AppleのBuild周りの知識を要求されます。
言語
Kotlin/Native | Flutter |
---|---|
Kotlin | Dart |
Kotlin/Native
言語的好みで言えば圧倒的にKotlinなのですが、X-PFを前提としたときK/Nは複雑性が上がり、可読性やメンテナンサビリティの低下につながる可能性があると感じました。
例えば、K/NではX-PF実現のために、1つのクラスを基本的には common
に実装しますが、
必要に応じて宣言だけをcommonで行い、実装は Android
iOS
...
と複数のファイルに分割できるようになっています。
逆に、各PFの実装からcommonの処理を呼び出すこともできますので、きちんと設計を行わないと簡単にスパゲッティーコードを生み出すことができてしまいます。
また、非同期処理周りでも制約があり、現状ではCoroutineでの実装をおすすめしているようです。Rxなどは各言語の実装によるため異なる挙動を示す可能性があるためでしょう。
このへんの設計の難しさをクリアすれば、クライアントのみならずサーバともビジネスロジックを共有できるため、夢が無限に広がっていきます。
Flutter
Flutterでは各PFの実装が処理の途中に挟まる事がないので、挙動の差異を気にする必要は最小で済むかなという感じです。
ドキュメント
Kotlin/Native
ドキュメントはありますが、ごちゃっとしていて全体像を理解するのに少し苦労します。とはいえ、不足していると感じるシーンは無く必要十分ではあります。
Flutter
ドキュメントの整備度合いはFlutterに一日の長がありそうです。 Dart初心者に対してもEffectiveDartも準備されており、言語的マイノリティーに対してある程度の安心感があります。
周辺ライブラリ
どんなライブラリが揃ってるかざっと見るのはawesome探すのが一番ですね。
Kotlin/Native | Flutter |
---|---|
awesome-kotlin-native | awesome-flutter |
Kotlin/Nativeのawesomeが全然awesomeじゃないよ。。。
依存管理
Kotlin/Native | Flutter |
---|---|
Gradle | Gradle |
どちらもASで開発できるので、必然的にGradleになるでしょう。わかる。
システム設計
まず、Kotlin/NativeやFlutterの特性を見ていく前に、プロダクト全体に対して与える影響をそれぞれ考えてみましょう。
Kotlin/Native
K/Nは逆に設計に注力する必要がある、ある程度の規模が見込まれるプロダクトに向いています。 Clientだけでなく、サーバサイドまで1コードで実装できるのはとても魅力です。
K/Nは各PFで積み上げた資産やライブラリを有効活用しつつ、ビジネスロジックを共通化するアプローチをとれるとれるので、 システム設計の観点ではK/Nだから生まれる制約というのは特に無く、それぞれのPFの制約に依存する感じになります。
Flutter
Flutterはミニマムで最速にリリースするのに向いています。
ただし、その分設計の自由度は少なく、他のアプリと差異を出すために特殊なことをしだすとFlutterのメリットは途端に消滅していく印象です。 サーバサイドについてもGoogleのサービスであれば一通りライブラリは揃っているけど、離れるほど少なくなる印象です。 サーバレスアプリケーションも(Googleのサービスベースなら)作りやすいんじゃないでしょうか。
ソフトウェア設計
それぞれのX-PFを採用したとき、それぞれどのようなソフトウェア設計が行えるでしょうか?X-PFは抽象化度によって、取りうるソフトウェア設計の幅に差が出てきます。
Kotlin/Native
K/NではBetaになって日も浅いこともあり、めぼしい設計アーキテクチャは見当たらない印象です。 Pure-Kotlin向けならありますが十中八九JVMに依存しており、そのままK/Nで使用できるとは限らないため判別が付きません。
また、K/Nは言語の項目で言ったとおり設計の難しさがあり、特に多人数で開発するプロダクトでは注意が必要です。 基礎設計を行う時間を取れるプロダクトでは選択する価値がありますが、大規模でとにかくリーンというプロダクトではそれなりの負債を覚悟しなければなりません。
逆にそこがクリアできるのであれば、設計の自由度は高く、好きなように実装できると思います。
Flutter
Flutterに関してはReactにインスパイアされたfluxアーキテクチャで実装されており、モダンなアーキテクチャを強制されます。 また、先行事例も多く参考を得やすいでしょう。
UI設計
UI設計に置いてはどういった長短があるでしょうか?近年の開発現場では非エンジニア職が直接UIの実装を行うシーンもしばしば見られます。 そうしたとき、UIの設計/実装のしやすさは判断基準の一つになります。
Kotlin/Native
K/NではUIは各PFで実装する事になります。それぞれのPFに適したUI設計ができる反面手間ではあります。 現在Android/iOSともにGUIでデザインできる機能が備わっているので、それがそのまま利用可能です。
Flutter
Flutterではレンダリングも独自で行っており、HotReloadに対応してるのが強みです。 UIパーツはWidgetという単位で公式/非公式問わず公開されており、ありものを拾ってくるのが容易です。 UIもコードで表現されるので、UIの修正が手間な印象を受けます。 ただし、Flutter自体がfluxアーキテクチャで動いており、そのへんの流れを知ってないと大規模なUI設計は難しい印象を受けます。
まとめ
いかがでしょうか?個人的な印象としては
- K/Nは選択肢としては選択可能であるが、現段階では自由度が高い半面、開発難易度も高い。
- Flutterは開発効率は高いが融通の効かない部分も多く、将来的に手詰まりになる可能性はある
という印象を受けました。 まとめとしては、まえがきに書いた事の繰り返しになってしまいますが、X-PFにおいて銀の弾丸は無いので、 自身の開発内容にあった特性のX-PFを選択していきましょう。
明日は id:karupanerura さんの 「非TLS時代のセキュアなデバイス認証の思い出」 です。