伊藤直也氏が語る、モダンなWebテクノロジーに共通する傾向とは?(後編) Chef、Docker、MicroservicesからReact、FRPまで。QCon TOkyo 2015
最新のITと関連技術をエンジニアの視点で掘り下げるイベント「QCon Tokyo 2015 Conference」が4月21日に都内で開催されました。
そのセッションの1つとしてKAIZEN platform Inc.の伊藤直也氏が行ったのが、「モダンWebシステム開発」と題して、最近のWebアプリケーションに関する技術に共通する傾向を探った講演です。
(本記事は「伊藤直也氏が語る、モダンなWebテクノロジーに共通する傾向とは?(前編) Chef、Docker、MicroservicesからReact、FRPまで。QCon TOkyo 2015」の続きです)
React
で、ここから少し話が変わります。Reactです、フロントエンド開発の話です。
ReactはFacebookが2013年の秋くらいに発表した、JavaScriptのViewのライブラリです。
いわゆるAjaxが登場してから、動的にWebアプリケーションの表示を構成するようになって久しいのですが、jQueryでDOM操作をごりごり書いて動的な表示を実現してきたと思います。
jQueryのコードは、DOMをこう動かしてね、ということをコンピュータに命令しているコードです。これはチープなものは簡単ですが、長くなってくるとだいぶつらくなってくる。なぜかというとDOM操作というのは非常に難しくて、その理由としてはDOMが状態を持っていること。
それからDOMはJavaScriptでいつでも書き換えられるグローバルな存在であることや、非同期にいろんなところから変更要求が飛んできて書き換えられるわけです。こうした中で、DOMの状態を間違いなく管理しなければなりませんん。
そういうコードは大きくなると見通しも悪くなるし、書くのも難しくなってくるわけです。
で、こういう状況をここ10年くらい、なんとなくフレームワークなんかでカバーしてきたわけですが、根本的に発想を変えられないか、と作られたのがReactです。
今日は「宣言的」という言葉が何回も出てくるので整理しておくと、「命令的」というのは、手続きを書いてコマンドをコンピュータに与えているのに対し、「宣言的」というのはそうではなくて、HTMLやSQLとか、実現したいことそのものを記述するのであって、あるべき状態や関係性を記述します。
ただ、宣言的と命令的なコードのあいだに明確な境界があるわけではなく、「より宣言的だ」といった感じで使われます。
Reactは、命令的だったビューの組み立てやDOM操作を、宣言的なパラダイムに戻すものです。
従来のWebプログラマは、サーバサイドでビューを組み立てるときにDOMをいちど構築すると、それを書き換えるときにはもういちど宣言的にDOMを書いてリロードすればよかった。
けれど、それをJavaScriptで動的に更新できるようになったせいで、動的に変えたい部分は命令的なコードを書くことになって、だから難しくなった。
Reactは、DOMに変えたいところがあれば、DOMを丸ごと書いて更新するというサーバサイドと同じ考え方でコードが書ける、ということをうたっています。でも、DOMを全部書き換えるとJavaScriptの良さをスポイルしているのではないかと思われるのですが、Reactにはそれを解決する仕組みが当然あって、それがVirtual DOMというものです。
Reactの内部にはVirtual DOMが控えていて、データモデルに変更があるとその差分をとってその部分だけ再レンダリングしてくれる。
このReactによって何が達成できたかというと、UI開発における状態管理からの開放なんですよね。
DOM操作は状態を管理管理しなくてはいけなくて、そこにつらいものがあったのですが、Reactを使うとその状態管理をほとんど意識せずに開発できるようになったと。
ここでも状態が出てきて、状態を管理するのが複雑なので、そういうのをなくしてシンプルにしようという動きですね。
ここでのスケーラブルはたくさんの人数でとか、長くとか、そういうことができるようになったと。
FRP(Functional Reactive Programming)
最近、リアクティブプログラミングというキーワードがよく出てくるのですが、聞いたことがありますか? (会場の3割くらいの手が上がる)
リアクティブプログラミングとは、パラダイムというかオブジェクト指向などと同じレイヤの言葉で、もともとはデータの流れを通じて変更を伝搬するとか、データの流れに反応してプログラムが動くとか言われていたのですが、あまりにも概念が広すぎて拡大解釈するとどこまでもいけるので注意が必要です。
で、オブジェクト指向プログラミングっぽさというものがあるのと同じように、リアクティブっぽさというのがあって、それは何かというとデータの流れを宣言的に扱う、というのをやっているのがリアクティブっぽいと言えます。
で、それに関数型プログラミングの考え方を組み合わせたのがFunctional Reactive Programmingです。
もともとはHaskellの世界で議論されていたプログラミングパラダイムが、C#やLINQと組み合わさってRxが出てきたのが発祥で、最近ではRxJavaとかいろんな言語での実装があります。
例を見ないとよく分からないので、これをご覧ください。+を押すと数値が増えて、-を押すと数値が下がる、というアプリを考えましょう。
これを命令的に書くとこうなります。
Reactive Programmingでは、まずデータの流れに着目すべき、という考え方です。
+ボタンのクリックイベントを、時系列に沿って流れてくるリストとして考えます。つながっているリストとして考えると、それはストリームと見なせます。つまり、イベントはストリームを流れる値と見なせます。
-ボタンも同様に考えます。ここでは+が4回押されるあいだに、-は2回押される、という感じです。
で、+ボタンを押したと言うことは1という値を入れたのと同じと考えられますので、+ボタンを1という値に変換します。-ボタンは-1に変換すると。
そしてこの次あたりがReactive Programmingの神髄なのですが、2つの違うボタンがあったじゃないですか、でも最終的に出る合計値は2つの操作を混ぜ込んだ結果なので、2つのリストを1つのリストにマージしてしまう。左から順に1、-1、1、1、-1、1のリストだと見なす。
このマージされたストリームを1つ前の値との算術結果に変換すると、1、0、1、2、1、2という画面の描画になると。
これをbacon.jsというライブラリを使って書くとこうなります。
まずbacon.fromEventでイベントをリストに変換して、-ボタンも同様に変換して。 、plusClickStream.map()で1に変換して、マージして、そのstreamをscanすると合計が出ると、それを描画すると。
わかったようなわからないような話ですが、着目すべきはstreamというデータ構造で、すべてのデータフローをストリームとして扱うわけです。
ストリームはただのデータ構造なので、単一の値でも配列の値でもぜんぶストリームの値と見なせて。ストリームというのはリストなので、リスト操作というのはぜんぶ関数型のイディオムで操作できると。
で、関数型言語というのは宣言的で、これまで見てきたような状態変化を避けるとか局所化するようなプログラミングパラダイムで書けるようになると。
で、思考の流れはこうです。
状態管理からの開放が達成できた、というのがReactive Programmingの背景だと考えられると。
これがさらに発展してきてUIプログラミングに応用できるよねと言う考え方になって、AndroidとかiOSでもReactive Programmingをする人たちが増えてきて、いま注目されているパラダイムになっていると。
まとめ
最後はまとめです。
昨今のパラダイムとかアーキテクチャは、いかにアプリケーションやバックエンドをスケーラブルにするかということに、やっていることが帰着する。
それは時代の要請で、クラウドネイティブとか非同期処理とか、時間と共に何かと複雑化しやすいWebシステム、というものがあって、スケーラブルにするというのは大規模なトラフィックをもっているサイトが横展開する手法だったのですが、長く運用するとか2~3人で開発するときでもスケーラブルにしておくといい、というのが分かってきた。
そこで、こういうアプローチは大規模じゃなくても使えるねということになってきましたと。
近年、着目したトレンドを見てきましたが、どれも複雑性への対策として状態管理にどう対応するかに同じパターンが見いだせますねということでした。
公開されているスライド「モダンWebシステム開発」
あわせて読みたい
「セールスフォース・ドットコムが買収される」というウワサが駆け巡った十日間
≪前の記事
伊藤直也氏が語る、モダンなWebテクノロジーに共通する傾向とは?(前編) Chef、Docker、MicroservicesからReact、FRPまで。QCon TOkyo 2015