[要約] reactの設計背景: 公開するAPIは最小限に -フレームワークを使わずにパターンを習得せよ-

日米のものづくりの比較分析は経営学や工学ではポピュラーなテーマだと思いますが(個人の見解です)、代表的な一つにアメリカはゼロイチが得意というものがあります(個人の見解です2)。

大胆に素早くアイデアを形にして、粗い品質でもパッと市場に出してフィードバックループを回すことで、まだ誰も検証できていなかった新しいモデルのプロダクト・サービスを確立する、といったような感じで。それに伴い得意な産業と苦手な産業も分類されます。緻密な品質が求められしかも集団作業が必要な車や都市建設なら日本の方が得意だけど、敷居が低くて何度もスクラップ&ビルドしながらスパイラルに作っていける映画やソフトウェア作りはアメリカの得意分野だといったように。(以上、「ハッカーと画家」の「第0章 メイド・イン・ザ・USA」から雑抜粋)

 

ハッカーと画家 コンピュータ時代の創造者たち

 

今回はその話自体は深追いしませんが、ふとしたきっかけで見たreactというwebライブラリの設計原則の話が「これがゼロイチ力の粋(すい)だよなあ」と唸ってしまったくらいにおもしろかったので、まとめてみました。

 

 

対象はカンファレンスのセッション動画で、react公式ドキュメントの「設計原則」の章で引用元になっているうちの一つです。reactの初期開発者の一人のSebastian Markbage氏が、フロントエンドのJavaScriptアプリを作るに当たって大事だと考えている原則を説明しています。その考えを実践して作ったライブラリとして、最後に少しだけreactが紹介されます。2014年秋のセッションなので、ほぼほぼreactが対外的にPRし出した年のはずで、初期開発の人たちの濃縮されたエッセンスが見られる時期かなと思います。

 

youtu.be

 

なお、翻訳は難しかったので諦めて、要約に切り替えました。セッションの書き取りが起こされているし、YouTubeでも字幕が付いているので、われこそはという猛者は突撃してみてください。

この記事では大幅に構成を変えて、セッションの最後の結論を最初に持ってきました。次に、その結論で述べられている4つの原則を一つずつ解説する形に再編成しています。

 

セッションの結論

f:id:t2wave:20201123174249p:plain

肥大化したライブラリ群を削ぎ落として、JavaScriptコードをシンプルで頑強にするために、4つの原則と実現方針を示す。

  1. 「標準規格を採用しよう」(しかし標準化の動きは遅いので実装されるまでに補填が必要)という原則のために「ライブラリではなくてポリフィルを使え」。
  2. スパゲッティコードを書こう」(抽象化されたコードより遥かに対処しやすいのでそんなに悪もの扱いしなくてよい)という原則のために「明示的で反復的なコードを書け」。
  3. 「シュガーは滅多に加えるな」という原則のために「バグを解決するためだけに抽象化を用いよ」。
  4. 「何か追加したら同じ量を消せ」という原則のために「スタックを一から再考して丸ごと削除せよ」。

 

1.標準規格を採用しよう

JavaScriptが他の言語と事情が違う点は、言語の成り立ちがブラウザと密接に結びついていることだ。ブラウザ戦争(JScriptなど)やリッチ化(ActionScriptなど)のためにさまざまな方言が作られ、2005年頃をピークにウェブ開発者たちを苦しめてきた。

 これを解決するためにさまざまなライブラリが作られてきたが、JavaScriptの学習難易度を上げる原因の一つになった。だいたい同じことができるが少しだけ違うたくさんの記法で溢れかえっているからだ。

f:id:t2wave:20201201001351p:plain

似たりよったりの大量のライブラリ群におさらばして、One JavaScriptにするために、できるだけ標準規格を採用しよう。問題は、標準規格の策定が合議制でなかなか結論を決められずに進展が遅いことだが、未実装の間はライブラリではなくポリフィルを使うようにしよう。ポリフィルなら権威付けられた標準規格の先行実装であり、標準規格が実装された時とそう変わらないからだ。名前空間も記法も同じだろう。(筆者補足: ポリフィルを使うのは今や常識だが、セッションは2014年のためこの辺は時代感がある。)

標準規格が無い場合もライブラリを使わず自分たちで機能を用意した方が良い。少し時間は多くかかるだろうが、そのほうが依存関係が少なくて自分たちでコードをコントロールできる。また、機能を作るためにコードと向き合うことでコードについての理解が深まるし、あなたのプログラミング能力も上達するだろう。 

 

2.スパゲッティコードを書こう

(筆者補足:  一般的には悪いプログラミングを指す「スパゲッティコード」 という用語を良いものだと主張する、本セッションの核になっている話。しかし、常識を覆す内容で難易度が高い。何を言ったかではなく誰が言ったか的なものになるが、Markbåge氏はFacebookで働いているだけでなくTC-39にも参加している平たく言えば世界でもトップクラスのJavaScriptプログラマーである。その氏がスパゲッティコードの方が良いと主張するから含蓄あるわけである。「悪い方が良い」のエッセイも解読の助けになりそうである。)

f:id:t2wave:20201203181809p:plain

スパゲッティコード(筆者補足:  スライドではフェットゥチーネ。故意にスパゲッティと区別しているようにも解釈できますがそのニュアンスが何かはわかりませんでした)とは、ほとんど抽象化されていなくて繰り返しの多いコードのことだ。

それを抽象化したりライブラリを利用して書き換えるとどうなるか?

  • クール
  • しかし、完璧なソフトウェアの涅槃状態などあり得ず、いつまでも満足できない。
  • 抽象化したレイヤーより上の層はすべて変更対象になるので影響範囲が広がりがち。
  • 理解が難しくなり、変更コストも上がるし新しいメンバーの学習コストも高くなる。
  • 特に大規模なフレームワークを採用すると、あらゆるユースケースAPIが用意されている代わりに、ブラックボックスが生まれて何が起こっているのかを実際に理解できなくなる。

f:id:t2wave:20201201004042p:plain  

出来の悪い抽象化するくらいなら何もしない方が良い。

  • 出来の悪い大型のフレームワークを使ったアプリをアップグレードしようとするより、書き殴られたスパゲティコード群を書き直す方が成功確率が高いのはなぜか?
  • 暗黙的なコードを明示化するよりも、明示的なコードを暗黙化する方が簡単だからだ。
  • たくさんの抽象化されたコードの構造を分析して改修するより、たくさんの繰り返しが存在しているコードを相手にする方が与し易いのである。
  • つまり、構造化されたコードよりスパゲティコードの方が優れている可能性がある。多くの現代のプログラマーにとって非常に直感に反することだろうが。

f:id:t2wave:20201203104612p:plain

では、どうするか?フレームワークの代わりにパターンを学ぼう。

  • なるべくライブラリを入れずに、すべてのコード資産を持ち続ける。
  • そうすれば、ライブラリのバージョンを気にしたり、少しだけ違う別のライブラリを同僚が紹介してくるような心配が無くなる。
  • ライブラリを入れたくなっても、なるべく自分たちで作るようにしよう。
  • ライブラリの使い方をStackOverFlowやネット検索で探すより、本を読んだりさまざまな方法でパターンを学び、コード資産を構造化する新しいパターンを作るのだ。
  • 一からパターンを作ることは、外部のフレームワークを使うより遥かに困難だが、学習曲線が大きく努力し続ければあなたをより良いプログラマーへ成長させる機会になるだろう。私がFacebookで学んだ最も重要な教訓でもある。

 

3.シュガーは滅多に加えるな

(筆者補足: シュガーとは、読み書きしやすくするなどの目的で、同じことをもっと短く書けたり別のやり方でできるようにすることを指す概念であるシンタックスシュガーをもじったものだと思われる)

f:id:t2wave:20201202001227p:plain

繰り返しを見つけてパターン化するにしても、標準化のドラフト(W3CやTC-39など)に載せられるくらいに一般化しよう。

  • 繰り返しを探して、バグになっている場合だけ、抽象化しろ。
  • 抽象化するときは、そのコストに見合う分だけのバリューを出せるように、さまざまなユースケースをカバーする一般化を行え。
  • どれくらいの一般化かというと、標準化のドラフトに載せられるくらい。(筆者補足:  Markbåge氏はTC-39のメンバーでもある)
  • 標準として受け入れられないなら、追加する価値がない可能性があり、その価値を再考または証明する必要があるかもしれない。 
  • 例えば、DOMはたくさんのメソッドや属性を持っているので、直接操作しなくていいようにDOMのトップにデータバインディングを追加することは便利なだけでなくバグも解く抽象化の合法事例である。

 

4.何か追加したら同じ量を消せ

f:id:t2wave:20201202001426p:plain

新しいパターンを加えたら、次の問題に備えリファクタしてコードを削除するべきだ。しかし、実際に実行するのは難しい。コードの削除を決断するためには、そのコードが関係する全てを学ばなければいけないからだ。例えパターンが標準化に採用されても、絡んでいる要素が多すぎてうかつに削除できないかもしれない。特に、あなたが既存のアイデアの上に継続的に構築し続けているときに起こりがちである。

したがって、できるだけAPIの表面積を小さくしてコードの削減を実現する。そのためには、スタック全体を一から再考するくらいにゼロベースの発想が必要になることもあるだろう。外部ライブラリを用いずにすべてのコード資産を自前で持ち続ければ、一からスタックを作り直すようなことも可能である。

Facebookのそのようなカルチャーから、reactは誕生した。reactはセッションタイトルの「Minimal API Surface Area」を実現した"パターン"である。

 

まとめ: ゼロイチ力の粋(すい)

  • どんなベストプラクティスだろうがゼロベースで再考する。
  • ベタ書き推奨。抽象化せずに明示化したままにすることで、どこにでもいける体勢をキープ。
  • 全体最適。巨人の肩に乗り、車輪の再発明を避ける。あくまで標準規格を採用せよという話で、セッション中では「標準最高」「権威大好き」という言い方。
  • 自前主義。内製は困難だが学習曲線は大きい。外部のフレームワークを使わずに自分でパターンを作ることは、Markbåge氏がFacebookで学んだ最大の教訓とまで言っている。全体最適とバッティングしないように、内製成果は標準化機構へフィードバックする。
  • ROIへの高い意識。抽象化するのはバグを解決できるとき。標準化に採用されないなら作らない/価値を考え直す。

 

(おまけ)なぜJavaScriptを使うのか?

f:id:t2wave:20201201003539p:plain

 

(おまけ2)いかがでしたか?あなたはこちらの動画も好きかもしれません

本記事で取り上げたセッションと同じく、react公式ドキュメントの「設計原則」の章で引用元になっているうちの一つです。既存の大規模で複雑で多数のシステム群の中で相互協調して小さく始められるようにいかにreactを設計したかの話です。

www.youtube.com