■ 1. 発表概要
- 発表者: 和田卓人(@t_wada)、2019年5月17日
- GitHub代表作: power-assert
- 著書監訳: プログラマが知るべき97のこと、SQLアンチパターン、テスト駆動開発
■ 2. 問題提起: どうしてこうなった
- JavaScript fatigue: 変化が速すぎるフロントエンド疲れ
- 限界集落: 停滞し、若者のいないプロダクト
- 変化の速さは陳腐化の速さでもあり、本質的でない変更を強いられる頻度にもなる
- 重要な変化と重要でない変化を見分けられない状態が問題の核心
- 軽微な変化をスルーできずに消耗する、あるいは重要な変化をスルーして詰む
■ 3. アプローチ: 変わるものと変わらないもの
- 変化が予想できないことだけは予想できる
- 技術の歴史から学び、過去から近未来の予測を試みる
- 技術の変化の歴史は一見すると振り子に見えるが、実は螺旋構造であり同じところには戻ってこない
- 重要なのは螺旋の「差分」と、それを可能にした技術
■ 4. 変わらないもの: 長生きしている技術
長生きしている技術として Unix、REST/Web、RDBMS/SQL が挙げられる
Unix哲学:
- 小さいのは良いことだ(Small is Beautiful)
- 一つのことをうまくやる(Make each program do one thing well)
- すべてはファイル、プログラムをフィルタに、標準入力と標準出力
- 成功失敗は終了ステータスで示す、KISS(Keep It Simple, Stupid)
- パイプを介して40年前のコードといま書いたコードが連携できる強さ
- REST / Web:
- すべてをURLで示されるリソースと考える(Addressable)
- 少なく、統一された振る舞い(HTTP Method, Uniform Interface)
- 状態を持たない(Stateless)、ハイパーリンクで状態遷移(Connectedness)
- 多様な名詞と少ない(制約のある)動詞という設計原則
- 良くできた分散システムとしてのWeb
- RDBMS / SQL:
- 強固で数学的な背景に基づく閉じた系
- すべてが関係/集合(テーブルも、クエリの結果も関係/集合)
- 少なく、統一された操作(SELECT, INSERT, UPDATE, DELETE)
- 最近ではSQLはRDBMSだけのものではなくなってきている
- 三者に共通するもの(制約がもたらす共有と高い相互接続性):
- インタフェースが狭く限定的
- 振る舞いの種類が少ない
- 実装に依存しない
- 接続と再利用が時間をまたいでいる
- 「すべては○○○である」という統一概念と閉包性:
- Unix: すべてはファイルとフィルタである
- REST/Web: すべてはリソースである
- RDBMS/SQL: すべては集合である
- 閉包性とは、結果も同じ概念に閉じるような系の強さを指す(SQLの結果とテーブルの同一視など)
■ 5. 変わるもの: 螺旋1(集中と分散)
- 技術変遷の流れ:
- Good Old Web(PHP, Java Servlet)
- EJB と SOAP と XML と SOA
- Ruby on Rails とモノリシックなWebシステムの立ち上げの早さ
- REST と PoX over HTTP
- JSONサーバとコンテナ技術
- microservices と逆コンウェイ戦略と BFF
- Swagger と GraphQL と gRPC
- クラウドネイティブとサーバレスコンピューティング
- 螺旋1の差分(何が変わったのか):
- クラウドが柔軟で動的な構成変更を可能にした
- 分散システムとしてのWebの理解が進んだ
- シェアドナッシング + スケールアウトという選択肢の確立
- JSONで必要十分だった
- ムーアの法則の限界打破はマルチコアではなく分散コンピューティングだった
- DockerやK8sなどのコンテナ技術の登場
- 新時代のアーキテクチャパターン The Twelve-Factor App(https://12factor.net/ja/)
- 現在のトレンドは開発組織を跨ぐスキーマやクエリ(Swagger、GraphQL)
■ 6. 変わるもの: 螺旋2(アプリとブラウザ・Web技術)
- 技術変遷の流れ:
- VB(オープン系): 2階層システム
- Good Old Web Site(PHP, Java Servlet): 3階層システム
- Flash: リッチクライアントの誕生
- Ajax: Re-discover JavaScript
- Webフロントエンドのフレームワーク乱立時代とキャッチアップ疲れ
- Native iOS/Android App: ブラウザでは満たせないUXの実現
- React登場後のフロントエンドとElectron
- PWA: Service Workerによる揺り戻しとdev.toの衝撃
- React Native, Flutter: 再びのクロスプラットフォーム時代
- 螺旋2の差分(何が変わったのか):
- アプリであれWeb技術であれ、主戦場はモバイルに収束してきている
- モバイル端末は、小さな画面上の可処分時間の奪い合い
- リリースプロセスの違いが品質のベースの違いをもたらす(MTBF と MTTR)
- PWAに関して、Service WorkerがモバイルにおけるネイティブアプリとWeb技術の差を縮められるかどうかが焦点
- エンゲージメントの強さとモバイル端末を占有させるUXを両立させられるかどうか
■ 7. Game Changerたち: 決定的な違いをもたらした技術
- 決定的な変化をもたらした技術:
- Ruby on Rails
- Cloud Computing
- Docker
- React
- (Envoy?)
- 量的な変化が質的な変化をもたらした(Rails/Cloud/Docker):
- Railsの生産性はスタートアップに必要な初期速度と仮説検証を可能にした
- クラウドはシステム開発のコスト構造やボトルネックを大きく変え、DevOpsを促した
- Dockerの圧倒的な速さと再現性の高さが従来の仮想化技術を塗り替えた
- 圧倒的な安さ・速さの獲得で不可能が可能になり、コードが事業そのものになる時代へ(Why Software Is Eating The World)
- 考えることを大きく減らした変化(React):
- 仮想DOMにより、富豪的にデータを更新してもレンダリングコストの心配が不要になった
- サーバサイドでテンプレートを毎回レンダリングするのと同じ感覚でクライアントのコードを書ける
- データ更新の方向が一方通行なので状態が一意に定まり、混乱しない(Single source of truth)
- Reactにより手数は増えたが、心配は減った
■ 8. スルーするか、しないか
- Game Changer そのものを採用する必要は必ずしも無いが、それらが変えた後の世界は知っておく必要がある
- 開発に関わる労力(コスト・心的コスト)を矢印で表すとする:
- 矢印を圧倒的に短くして、コスト構造を大きく変えるもの
- あるいは矢印を折るような、ジャンルそのものを不要にするもの
- インパクトのある Game Changer とその後の世界はスルーしがたい
- そこまでではない変化は「お好みで」となる
- その技術が何のために出てきて、何をどのくらい変化させるのか見切れればスルーできる
■ 9. 「お好み」を表現する軸を持つ: Worse Is Better
- Richard Gabrielによる「The Rise of Worse is Better」を参照
- 美しく抽象に優れたLispに対してUnix/Cが勝利した理由を分析した文書
- ソフトウェアの設計を簡潔性、正当性、一貫性、完全性の4観点から考える
- 二つのアプローチ(MIT/Stanford vs. New Jersey)が存在する
- 簡潔性(Simplicity):
- MIT/Stanford: インターフェースが単純になることの方が、実装が単純になることより重要
- New Jersey: 実装が単純な方が、インターフェースが単純なことより重要。単純さが設計において最も重視されるべき事柄
- 正当性(Correctness):
- MIT/Stanford: 設計はすべての点において正しいものでなければならない。誤りは許されない
- New Jersey: どちらかといえば、正しいことよりは単純なことの方が重要
- 一貫性(Consistency):
- MIT/Stanford: 一貫性を保つためには完全性や単純さを多少犠牲にしてもよい
- New Jersey: 単純さを保つために一貫性は犠牲にされることがある。あまり起こらない状況のために実装を複雑にするよりは、それを捨てる方がよい
- 完全性(Completeness):
- MIT/Stanford: 簡潔さのために完全さが大きく損なわれることがあってはならない
- New Jersey: 他の条件のためならば完全さはいつでも犠牲にしてよい。実装の単純さよりは完全性を犠牲にするべき
- 二つのアプローチの要約:
- MIT/Stanford: コードがいくら複雑になろうとも、正しいことをせよ
- New Jersey: ユーザの負担が増えたとしても、コードを単純に保て
- Worse Is Better の本質(Eric Raymondの視点):
- MITモデルは抽象に優れたソフトウェアを導くが、New Jerseyモデルの方が伝染性(propagation characteristics)という特性では優れている
- 設計の正しさや完璧さよりも、もっとも速く広がるもの(伝染性/感染性のあるもの)がもっとも強い
- 「とりあえず正しいことの半分はできるものを作り、ウイルスのように広める方がよい。いったん人々がそれに騙されれば、正しいことの90%まで改善が行われるだろう」(Richard Gabriel)
- ソフトウェアの競争力としての実装の単純さや機能の少なさの優位性の話であり、汚く早く書いた方が良いという話ではない
- 和田卓人によるWorse Is Betterの解釈:
- 設計の正しさ/美しさと実装の単純さが対立するときは、実装の単純さを選択した方が、漏れのある抽象になったとしても現実の問題を解決し、開発参加のハードルが下がり、進化的な強さを獲得できる
- Worse Is Worse(Jim Waldo, Sun Microsystems Distinguished Engineer)による反論:
- 「Worse is better」というスローガンが、やっつけ仕事や粗悪な設計を正当化するキャッチフレーズとして誤用されている
- 元の記事の真意を理解せずにキャッチフレーズとして使われることへの警告
- 顧客を欺き、自分たちの作品を貶める考え方として批判
■ 10. Postmortemを読もう
- 競争に負けたソフトウェアの責任ある立場の技術者が書いたふりかえりには多くの学びがある
- 事例: RethinkDB vs. MongoDB:
- RethinkDBは正しさとシンプルさと一貫性を訴求したが、ほとんどのユーザにとって意味のある成功指標ではなかった
- MongoDBはデータストレージを高速にし、人々がプロダクトを素早く世に出せるようにした(Worse Is Better的な戦略)
- MongoDBは後からアーキテクチャの問題を修正し、現在は素晴らしいプロダクトになった
- 事例: Bazaar-NG vs. Git:
- 必須ではない機能に注力し、不必要な機能を削ぎ落とさなかった
- コードベースが大きくなるにつれ、バグの範囲も広くなりリファクタも難しくなった
- Gitレポジトリを直接扱えるという機能追加が、余計な複雑さとアーキテクチャ上のバグを生んだ
- Linus Torvaldsの言葉:
- "Don't underestimate the power of survival of the fittest. And don't EVER make the mistake that you can design something better than what you get from ruthless massively parallel trial-and-error with a feedback cycle."
■ 11. まとめ
- 変わるもの: 技術の変化は螺旋状であり、螺旋の差分とそれを可能にした技術を理解する
- 変わらないもの: 生き残る技術には特徴がある。その背後にある抽象の力を理解する
- Worse Is Better とは、やっつけ仕事の優位性の話ではない
- 技術に対する様々な評価軸と、それを表現する語彙を育む