Edited at

私がJavaからDartに移行した理由

More than 1 year has passed since last update.

※ このポストはDavid Morganの許可を得てWhy I moved from Java to Dartを翻訳し、投稿しています。


ある人はJavaScriptからDartに移行したと聞いています。まあ、私の旅は少しばかり違いますが。私はJavaからDartに移行しました。そして、adwords.google.comの一部も一緒に。

App.java ⇒ app.dart.png

AdWordsはGoogleの収益の中心であり、今まさにDartで書き換えつつあります。ところが、私が仕事しているAdWordsの一角(スキップ可能なYouTube広告を売る部分)は既に2014年からDartで動いていました。

我々のチームはDartを使うように指示されたわけではなく、そう頼まれたのでさえない、というところが面白いところです。我々はDartの能力を見出し、試す価値があると判断したのです。

重要なのは、ガラポン再構築を行わなかったことです。以前はJava/GWTを使っていましたが、Dart移行時には、ブラウザ上でDartと段階的に統合出来ました。Dartに精通し、またDartが成長するに連れDartに熱狂するようになり、最終的にはほぼ全てのブラウザ上のコードをJava/GWTからDartに書き換えました。

ここからが、DartがJavaよりも優れている主な理由です。


1. Dart SDK

あなたがJavaでコードを書いた経験が豊富なら、最も不満に感じる部分は標準ライブラリではないでしょうか。その鍵となる決断はずっと前に下され、もはや後戻りできません。JavaのIterableとDartのIterableを比較するだけで、世の中がどれだけ進歩しているか理解できます。

つまり、Javaでのプログラミングの最良の方法はサードパーティーのライブラリを使うことです。GoogleではGuavaを利用していますが、かなり素晴らしいものです。例えば、GuavaにはFluentIterableがあります。それでも、SDKの一部ではなく、いまだに二級市民です。

Dartには全て最初からやり直すチャンスがあり、それを実践してみせました。JavaでならFluentIterableを使うであろう例を示します。

print(

[1, 2, 3].where((x) => x.isOdd).map((x) => x + 10));
-->
(11, 13)

DartPadで実行


2. コールバック、Future、async/await

あなたがJava/GWTでコードを書いた経験が豊富なら、「コールバック」という言葉に無意識に反応するようになっているのではないでしょうか。単にその言葉を聞いただけで冷汗をかいているはずです。

私個人は、一連のRPCの連鎖における異なるイベントを処理するためにコールバックのコールバックのコールバックの羅列である酷く恐ろしいコードを書き、メンテナンスしています。

これは比較的マシな例です。

public void getFoo(AsyncCallback<List<String>> callback) {

getThenFilter("foo", callback);
}

private void getThenFilter(
final String parameter,
final AsyncCallback<String> callback) {
makeRequest(new AsyncCallback<List<String>>() {
void handle(List<String> values) {
List<String> filtered = new ArrayList<>();
for (String value : values) {
if (value.startsWith(parameter)) {
filtered.add(value);
}
}
callback.handle(filtered);
}
}

DartにはFutureが有り、それに沿って標準ライブラリが設計され、全てが解消します。Dartが私に語りかけてきた瞬間でした。より良いコーディング生活のためにまさに必要なものが手に入ります。

Future<List<String>> getFoo() {

return _getThenFilter('foo');
}

Future<List<String>> _getThenFilter(String parameter) {
return makeRequest().then((result) =>
result.where((string) => string.startsWith(parameter))
.toList());
}

これに留まりません。Dartチームはasync/awaitキーワードというFutureをお洒落に使う方法を議論ていました。ただ"await"と書くだけで、あたかも同期型であるかのように非同期コーディングを進められて、すべては舞台裏で処理されるようです。

そして、現実のものとなりました。長年Javaで開発してきた者として、単なる仮説による言語変更議論は自分の仕事の何の役にも立たない、と思えるようになった瞬間です。歓喜でした。

Future<List<String>> getFoo() {

return _getThenFilter('foo');
}

Future<List<String>> _getThenFilter(String parameter) async {
var unfiltered = await makeRequest();
return unfiltered.where(
(string) => string.startsWith(parameter)).toList();
}

DartPadで実行


3. ナンセンス無用、ボイラープレート無用

JavaからDartに移行するとコーディング生活を楽にする非常に多くの機能に出会います。

一つだけでもJavaプログラマーを笑顔にします。一度に全部なんてもう我慢できません、良い意味で。


4. さらに前へ

Dartの進化はasync/awaitで留まることはありません。最近はジェネリックメソッドの文法をサポートしました。非Nullタイプの試みも進められています。型システムはStrong Modeで改修されつつあります。

Dartは徹底的に実用本位に進化します。全ての機能は実用コードにおいて快適に動くことが求められます。なので、今後も新しい機能が登場するでしょう、良い機能だけが。


5. Web適正

最後に、DartにはWeb UIフレームワークがあります。実は我々はAngularDartの影も形もない時からWeb UIで始めています。その後AngularDartを利用し、現在はAngularDart 2です。全てに共通で、軽量、HTML風テンプレートがあります。



値不変性の探求

私の視点からはDartに唯一欠けていると思うものは、適切な不変コレクションと不変型のサポートです。なので、誰かが使えるパッケージを書いてくれることを期待しつつも、我々のチームで利用する何かしら動くものを急ごしらえしました。

でも、最終的にオープンソース公開に堪えるものの作成に時間を費やしました。built_collectionbuilt_valueの誕生です。


以上です。Dartはプライムタイム出演の準備万端です。我々がAdWrod for Videoでしたように、巨大で、ミッションクリティカルなWebアプリケーションをDartで構築できます。またはFlutterを手にAndroidとiOSのモバイルアプリ開発を始めることも出来ます。加えて、最近私が書いた記事のように、サーバサイドDartはクライアントサイドDartと共同して非常に上手くやります。


私自身の個人的な話について; Dart Developer Summitで公演を持った後間もなく、Dartチームに入りました。つまり、結果的に私そのものが「Dartに移行」しました。


追記

Redditでの本記事に対する反応に対して幾つか注記します。


SDKを補完する第三者ライブラリとして、Java 8でstreamがほぼ同じ機能を提供するFluentIterableは特段良い例ではありませんでした。

次に思い浮かぶSDKの比較例はファイル読み込みです。Dartでは単に new File(‘foo.txt’).readAsStringSync() とかくか、もし同期処理にしたくない場合 await new File(‘foo.txt’).readAsString() と書けます。Javaでは、最新の正しい書き方が何か、いつも探す必要があります。

他の例を挙げることは容易ですが、これは驚くべきことではありません。オブジェクト指向言語が辿った長い道のりの中で、DartのSDKはJavaのAPI設計よりもずっと後に構築されたのですから。


この記事はブラウザ向けにJSにコンパイルするDartについて書いている、ということを強調しておきたいと思います。私が行った移行はJava/GWTからDartです。


そして最後に、私が仕事で携わってきた数ある言語の中で、Javaは今でも2番めにお気に入りの言語であることを言っておきたいと思います。