Caution
この記事はDHHファンの妄想によるシナリオが多分に含まれます。 というかほとんどです。
成り立ちや考え方が間違ってることも当然あるように思うので話半分で読んでください。
これは一体
前回かいた妄想的DHH理解のエピソード0的な話です。
妄想的DHH理解では、DHHがどういう過程で今のRailsフロントエンドに達したかの話が主題でしたが、そこでは「なぜ〜を選ばなかったか」は説明されていませんでした。
彼はモノリシックを愛したり、トレンドと真逆のアプローチでフロントエンドに新しいレールを引き始めたりするので、単に彼が天邪鬼であったり車輪の再発明大好きおじさんとして捉えられがちですが、実は太い太い一本筋をもった技術選定をし続けてるってことが広まればいいなと思ってるファンの記事です。
前提知識
前回とほぼ同じです。
DHH
Railsの生みの親、Rubyist。 実はカーレーサーでもあります
Basecamp(社)
DHHがCTOやってる会社
Basecamp(サービス)
Basecamp(社)が開発してるプロジェクト管理ツール
ある日スタートアップ向けにスピーチをするDHH
「なんで大企業作ったわけでもないし、ユニコーン企業作ったわけでもないちょち場違いなワイがここにおるかわかるか?」
「安定した顧客基盤を築いて、それに伴う利益で最高の仲間達を養えて暮らしていければ別にそれでいいじゃないかっていう価値観も世の中にはあるんやでってことを示しにきたんや」
「周りはユニコーン企業を目指せとかさもなくば去れみたいなことを言ってくるだろうけど、ワイは仕事の他にも趣味もあるし、家族もいるし、もっと技術探求したい思いもある。
今のワイみたいに地味に根を張った企業としての生き方だってありやってことを知ってもらいたいんや」
ここから見えるDHHの世界観は会社を大きくするというよりは、余剰開発時間をたくさん作って自己投資したりして人生をよりハッピーなものにしていきたいんやというところ
いかにして余剰開発時間を捻出するか
時間は増えるものではないので、余剰開発時間を作るためには開発の効率をあげるところが基本的な焦点になる。
そこで彼のとったアプローチは彼の口癖でもある「概念的距離の圧縮」です。
I spoke about conceptual compression and using that to arm the rebels in my 2018 RailsConf keynote. What we've done with NEW MAGIC is simply an incarnation of these principles. https://t.co/V8yU8YJ1NH
— DHH (@dhh) November 27, 2020
彼はこの単語をいろんな場面で使うのでなんだかなんのことを言ってるか見えづらいところもあるだろうけど、わたしは実は意外とシンプルなことを言ってるんじゃないかなーと捉えてます。
続く章でそれぞれ説明してみます。
アプリーケーション と DB
「アプリケーションってだいたいDB(のテーブル)とコミュニケーションするけど、この手続きって煩わしいな〜、接続してSQLなげて結果をもらって、それをようやくModelに食わせて〜みたいなの毎度毎度コード書きすぎてて辛いわ」
「SQLとかコネクションとか意識せずに、もう最初からModelとテーブルが表裏一体な感じでRubyから直接いじれたらコード書く量激減してハッピーやのにな〜。 よっしゃいっちょやったろ! ActiveRecordパターンや!!!」
これこそ彼の言う概念的距離の圧縮の考え方なのかな〜と捉えます。
アプリケーションとDBの距離が遠いから手続きが増えてコードが肥大化してしまう。 ならばとこれを簡略化したActiveRecordパターンはアプリケーションとDBの距離を圧縮(≒密結合)した実装パターンになるわけです。
これが彼の生産性を大幅に引き上げることに成功して、彼はこの概念的な距離を縮めることで開発効率をぐっと高めることを勝ちパターンにするようになりました。
サービスとサービス
「なんや巷でマイクロサービスゆうのが流行ってるらしいな? 鬼のような速さでドッグフーティングしてみたけどええもんやなこれは。」
「皮肉やないで? ただこれがええように思えるのはGAFAみたいな超デカ企業だけやな。 ワイとか世の中のほとんどの規模感の場合はサービスとサービスの概念的距離が遠くなってサービス間の連携のためのコードが大量に増えて残念なことになる未来が見えるで」
「モノリシックでコードが汚くなるんは、タイトすぎるスケジュールとゆるすぎる規約と、単純な技術力の問題やろ。ワイはサービス間の概念的距離のないモノリシックが好きや」
「一昔前にコメット(XHR polling)でチャット作ってそれをサービスに入れてた時はそれだけめちゃくちゃ負荷やばかったからそれだけは流石に切り出して前哨基地みたいな感じで配置したけど、俺はそれをシタデル(前哨基地)と呼ぶで! こっちはモノリスを軸とした派生系でお気に入りのパターンや」
そんな感じでDHHはモノリシック大好きおじさんとして有名なのですが、それは単なる逆張りではなく彼の余剰開発時間の生み出し方(概念的距離の圧縮)とマイクロサービスのアプローチが真逆のところにあるからなのですね〜
HTMLとJavaScript
DHHはStimulusも概念的距離の圧縮をフロントエンドで実現するための要素だと言ってます。
Stimulusで圧縮した二つの概念は「HTML」と「JavaScript」です。
従来のJavaScriptはセレクタをAPI(document.querySelector等)になげてHTMLを取得し、加工するという処理を行っていましたが、それってまさに最初の例のアプリケーションとDBのような関係ですね。
そこには概念的距離が存在しており、それによる多くの手続き処理が発生していたわけですね。
let button = document.querySelector('button');
button.addEventListener('click', fn1, false);
function fn1(evt) {
let inputTargets = [...document.querySelectorAll('input[type="text"]')];
inputTargets.forEach(...)
// ...
}
もしこのコードが
// in HTML
// <button type="button" data-action="click->hoge#fn1">
// <input type="text" data-hoge-target="input">
fn1() {
this.inputTargets.forEach(...)
}
とかければ随分コード量が減りますよね。
StimulusはMutationObserverを利用してDOMとJavaScriptの概念的距離を圧縮して、HTMLをJSオブジェクトのプロパティとしてすぐ近くにあるもののようにアクセスできるようにしたことで概念的距離を圧縮したわけです。
なぜ他のライブラリではなかったのか?
ReactやVueといったライブラリもアプローチは違えどStimulusと同じくHTMLとJavaScriptの概念的距離を極端に縮めることに成功したライブラリです。
概念的距離の縮み具合だけでいうとReactやVueの方がStimulusよりも緊密であるとさえ思えます。
しかし目線をサーバサイドアプリケーションとクライアントサイドアプリケーションの概念的距離に変えてみるとどうでしょう?
Viewが独立していて、サーバサイドアプリケーションとなんらかの通信をとることが必要になります。
これはその目線において二つの概念の距離が開いてしまっていると言えます。
この二つの距離が開くことによってデータを振る舞いをもったモデルという便利な形から通信可能なデータ形式に変換してわたすという手続きが発生することを嫌ったのでしょう。
本来であればViewがモデルから欲しい情報をうけとればよかったものが、エンドポイントでそのページ内で必要なデータセットとその構造を全て洗い出し送り出すという注意深さが増えたのです。
もちろんこれによってそのページの依存や必要なデータがクリアになるといったメリットはあるし、それこそが尊いという人がいることも理解してますが、DHHの思想からすると逆に悪手だったわけです。
最後に
この彼のアプローチは、あくまで彼が余剰開発時間を最大化したいという目的を持っていることが大前提となってなりたっています。
別の目的があれば最適解は変わるだろうし、環境や規模がかわった場合も同じです。
いろんな考え方があってよいと思うし、DHHもすべてこの側面からしかものを考えてないというわけでもないと思います。
トレードオフがあって、それでも我々はこの方法を選ぶのだと語ることもあります。
この記事では彼の方針には常に一本の軸があって、実装は都度かわれど方針は揺るがずまっすぐ同じ方を向いているということが伝われば嬉しいなと思います。