Skip to content

Instantly share code, notes, and snippets.

@tai2
Last active December 8, 2018 08:55
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tai2/db93b07ccaefe76556ebc4fc81f73f0a to your computer and use it in GitHub Desktop.
Save tai2/db93b07ccaefe76556ebc4fc81f73f0a to your computer and use it in GitHub Desktop.
おまかせ vs アラカルト(Railsdm 2018 Day 4) 付録

おまかせ vs アラカルト(Railsdm 2018 Day 4) 付録

参考リンク

Railsはおまかせ(Rails is omakase翻訳)

DHHによるおまかせ思想を解説したエッセイ。半分くらいは行儀の悪いユーザーに対する愚痴。

Rails Is Omakase: A Dramatic Reading

Rails is omakaseを読み上げてる動画。エモい。

The Rails Doctrine

Railsの基本思想を解説した文書。「メニューはおまかせ」や「鋭いナイフ」などDHH独特の考えかたが見られる非常に興味深い文書。

良いモジュールの探しかたとモジュール哲学(browserify-handbookから抜粋翻訳)

browserify作者のsubstackによるNodeのモジュール哲学が垣間見られるドキュメント。

merge with fs.extra and fs-extra #17

substackの作ったnode-mkdirpという単機能モジュールを大きな便利パッケージにまとめたほうがいいのではないか?という提案。substackは小さなモジュールがいいんだと提案を断わっている。小さいほうが検索しやすくなるという議論など。

Unix Philosophy and Node.js

npm作者&元Nodejs BDFLのisaacのエントリ。Node.jsにはUnix哲学(単機能モジュール)が息づいていることが述べられている。

Unix Philosophy と Node.jsのモジュールの作り方

会長こと古川さんのエントリ。上のNode.jsのモジュールとUNIX哲学を結び付けて論じている。

https://blog.sindresorhus.com/small-focused-modules-9238d977a92a

Node.js会の著名クリエイターSindre Sorhusが、小さい単機能モジュールがなぜ良いかを説明している。

Revert "Ignore /bin on new apps" -- given the move to default binstub…

binstubsをgitignoreに含めるかどうかに関する白熱した議論。DHHは、rbenvを使わないユーザーのことも配慮するべきだという意見を一蹴した。それはおまかせメニューではないから。

On Node Framework Popularity

Node.jsでのWebフレームワークの人気について。Expressが圧倒的に人気という結果。

シンプルさの必要性

一見似ていて混同されがちな、SimpleとEasyという概念の違い。

Seaser2終了から学ぶフレームワークとの付き合いかた

「ここまでの規模感のSeasar2が終わる可能性があるということを真剣には考えていなかった」と述べられている。

About Rails concerns

Railsのconcernの難しい部分と、使うならどう使うべきかが解説されている。

台本

「Rails is omakase」っていう言葉は聞いたことありますか? The Rails Doctrine、日本語だと「Railsの基本理念」っていうドキュメントがあって、 そのなかで原則のうちのひとつとして挙げられてるやつです。

このセッションでは、おまかせな環境と、 その反対のアラカルトな環境を対立させます。 それから、このテーマについて考えるための「観点」を10個列挙します。 で、列挙しながら、こいつらを比較していきます。 比較することで、Railsがどういうものなのか、改めて考えてみる、 っていうのがねらいです。

それじゃあ、まずは「メニューはおまかせ」という原則のおさらいです。

DHHはエッセイで次のように表現していました:

料理人のチームが素材を選び、APIを設計し、きみのかわりに食べる順番を決める。
それらは、なにがおいしいフルスタックフレームワークの足しになるかという、かれらの考えにもとづいている。

おまかせな環境では、ユーザーである開発者は、個別にパーツを選択するっていうことがありません。 シェフであるところのライブラリ作者が、かわりに一から十まで決めてくれるからです。

おまかせ環境を使っておけば、「ある意味では」熟練の経験は不要です。 「ある意味で」というのは、熟練の経験が必要なこともあるっていうことですが、これはあとで説明します。

席に座って、シェフが料理を作るのを見ながらですね、口をポカーンと空けて待っていれば、 それだけで、おいしい食事を楽しめてしまうんです。 ただし、シェフの好みが自分の口に合わないということも考えられます。 そういうときは、まー、ちょっと困っちゃいますよね。

ともかく、Railsっていうおまかせメニューを受けいれちゃえば、もうそれだけで、 完全に動作するWebアプリケーションを作ることができちゃいます。

ORマッパー、URLルーティング、テンプレートエンジン、メール送信、ジョブ管理などなどなど、 開発に必要なものは、最初っからぜんぶメニューに入ってるわけですからね。

おまかせのちょうど反対に、アラカルトな環境があります。 アラカルトな環境では、自分で、メニューに載っている料理、 つまり、さまざまなパッケージの一覧を把握して、 その中から自分の好みに合った一品を逐一選んでいきます。

モジュールがどのように作られているかを気にする必要はない。
知らなきゃいけないのは、�レゴの城を作るために、レゴブロックをどう使うかだけだ。

これは、アラカルト派の著名なクリエイターsindresorhusさんの言葉です。

Express.jsというライブラリは聞いたことありますかね? これは、Node.jsで最もポピュラーなWebアプリケーションのためのパッケージです。 これは、典型的なアラカルト環境です。

Express.jsには、

  • ルーティング機能と
  • リクエスト・レスポンスオブジェクト
  • そしてミドルウェアの仕組みが含まれます

ですが、提供する機能はほんとうにそれくらいのものです。 Node.jsランタイム上の非常に薄いレイヤーになっています。 ですから、これだけではちゃんとしたアプリは作れません。

ストレージ層はSequelizeにするのか、mongooseを使うのか、それともRealmを使うのか。 Viewのレンダリングは、Pugなのか、Mustacheなのか、EJSなのか。 ログ出力、メール送信、ジョブ管理なども考えなくちゃいけません。

アラカルト環境では、デフォルトの選択肢がありません。 なので、こういったことを逐一自分で調べ、比較し、選択しなくっちゃいけません。

もちろん、ある程度定番の選択肢は存在します。 しますが、すくなくとも、それが何なのかは調べる必要があります。

一方、Railsはどうでしょう? 公式に乗っかれば、とにもかくにもアプリケーションを作りはじめられます。 アラカルトとはずいぶん違いますね。

さて、ここまでで「おまかせ」と「アラカルト」の基本的な概念はわかりました。 次は、もう少し詳しくこれらを比べていきます。 10個の観点から、どちらに分があるのか考えてみましょう。

最初は、インテグレーションコストです。 コンポーネントを組み合わせて繋げるときの話ですね。

[おまかせは組み合わの問題を自分で解決しなくていい]

おまかせ方式では、フレームワーク提供者ががんばってくれます。 ユーザーのかわりに、組み合わせたときの動作テストをしてくれます。 また、最初から、組み合わせて使うときのことを考えて設計してくれてるはずです。

仮に、モジュールの組み合わせで起きる問題があるとします。 同じフレームワークのユーザーなら、同じ問題に遭遇する確率が高いです。 なんでかというと、フレームワークのメニューが同じだからです。 だから、問題に対処するのに、多くの人が力を合わせて取り組めます。 いわゆる「目玉の数さえ十分あれば、どんなバグも深刻ではない」というやつです。

他方、アラカルト方式ではどうでしょう。 ライブラリは単体での動作確認はきっとしています。 でも、他のライブラリと組み合わせたときのテストは? していないかもしれません。

ライブラリAとBを使いたいときに、 組み合わせて使うために必要な機能が足らなかったり、 インターフェイスが十分に柔軟でなかったりすることもあります。 そういうときは、ライブラリ側の機能追加や修正が必要になってしまうかもしれません。

また、アラカルトでは、自分と同じ組み合せを選んでいる人はすくないです。 すくなくとも、おまかせほどは多くないでしょう。 問題が、自分だけの組み合わせで発生するなら、自力でなんとかして解決するしかありません。

したがって、定義からほとんど自明なことではありますが、 インテグレーションコストでは、おまかせが上なんじゃないでしょうか。

次は、アプリ設計の自由度についてです。

Railsにおけるおまかせの概念では、必要な部品をすべて提供します。 同時に、オプションで、他の部品に置き換えることも許しています。

たとえば、自動テストを書くときに、デフォルトのminitestを使わず、rspecを使っている人は多いと思います。 ERBを使わずにHAMLを使う人、 Active Jobを使わずにSidekiqのAPIを直接使う人、 Acitve Storageを使わずに他のファイルアップローダーを使っている人などもいるでしょう。

Active Recordでさえ必須というわけではないです。 trailblazerを使ってアーキテクチャそのものを変形させることさえできてしまいます。 こういったことはすべて、各コンポーネントの独立性がきっちりと保たれているからこそです。

では、Railsのおまかせは、アラカルトと同じくらい自由なのでしょうか? おまかせには、さながら新体操の金メダリストのような柔軟性が、あると言えるのでしょうか。

Railsの設計がどれだけ柔軟でも、変えられない部分もあると思います。 たとえば、CoCっていう根本的な概念は変えられません。 仮にActive Recordのみ取り出してSinatraから使ったとします。 それはもはやRailsと言えるのでしょうか。きっと言えないでしょう。
内包されるコンポーネントが組み合わさってこそのRailsなのです。

アラカルトでは、どのようにレゴブロックを組み合わて、どのように繋げるのか。 また、ブロックのない部分を自分のコードでどのように埋め合わせるのか。 こういったことをトップダウンで縛りつけるような圧力がありません。

というわけで、アプリ設計の自由度はアラカルトの勝ちです。

3番目の話題は、要求されるスキルです。

おまかせでは、シェフがユーザーの代わりにメニューを考えてくれます。 ということは、おまかせなら、ユーザーのスキルが低くても使えるっていうことなんでしょうか? たしかに、Railsの基本理念において、そのようなことがほのめかされています。 いわく、自信を持ってツールを選択するのは大変なことであり、 おまかせはユーザーがエキスパートであることを要求しない、だそうです。

ですが、同時に、正反対のことも述べられています。 Railsは、研ぎ澄まされたナイフを意図的に提供するものである、と書かれているんです。 怖いですねえ、恐しいですねえ。

それは、ともすれば、自分自信の身体をも傷つけかねないナイフです。 こういったものの代表例として、モンキーパッチや、Concernが挙げられます。 モンキーパッチの危険性は言うまでもないですし、Concernはモデルの肥大化を招きます。 私見ですが、Concernは可読性を著しく下げてしまうので、あまり使いたくありません。

しかし、プログラマーは、こういう難しい道具の使いかたを身につけられるはずだ、 って言うんですよ、Railsは。

Railsは、単なるお客さんのためのものではないんです。 シェフや、すくなくともシェフになろうとしている人のための道具なのです。

おまかせは、あくまでもメニューを用意してくれるだけです。 スキルが低くても正しく使える、ということとはあまり関係がないとぼくは思います。

アラカルト環境では、自分で選択肢を比較検討できる十分なスキルが必要になります。 ただ、公式メニューがなくても、他の誰かが考えてくれたフルコースの記事とか、サンプルコードだとかは手に入ります。 非公式なレシピでカバーすることは十分に可能だと思います。

要求されるスキルについては、おまかせだから要求スキルが低いとも、その逆とも言えないと思います。 Railsみたいに、メニュー自体が高いスキルを要求するっていうこともあるわけですからね。 ということで、ここは引き分けです。

次の観点は、知識・ノウハウの伝搬です。

多くの人が同じものを使うことが、おまかせのメリットのひとつです。 共通の知識や経験を持った人がたくさんいると、プロジェクトに良い効果があります。 運営する側にとっては、参加してくれるメンバーを探しやすくなりますし、 個々の開発者にとっては、参加するハードルを引き下げてくれます。 開発ノウハウなども、得られやすくなると期待できますし、 問題に遭遇したときには、多くの人と共有できます。

一方、アラカルトでは、環境は共有されるものというよりは、個人のものという側面が強いです。 だから、知識が分散して、みんなで力を合わせづらくなります。 問題が自分固有のものになってしまう可能性は、相対的に高いと言えるでしょう。

そう考えると、知識・ノウハウの伝搬は、おまかせのほうがうまくいきそうです。

5番目は、バージョンアップのしやすさについて。

おまかせソフトウェアは、リリースのタイミングを全体で統一しているものが多いです。

Railsは、コンポーネントが独立していて、個別にパッケージ化されています。 Railsのようになっていれば、リリースを全体で統一する必然性は、ないようにも思えます。 ですが、ともかく統一されているものが大半のようです。

たとえば、PythonのフルスタックフレームワークであるDjangoでは、全体が一つの配布単位になっています。 これは、Railsとは異なる点です。

本質的に巨大である以上、リリースのコストが大きくなります。 個々の機能単位で実装が完了しただけではダメです。 全体で歩調を合わせる必要があります。 ですから、完成している機能をユーザーに届けられるタイミングが遅くなります。

一方、アラカルトではどうでしょうか? 個々の小さなコンポーネントレベルでテストが完了すれば、即リリースできます。 リリースサイクルを小さくしやすいと言えるでしょう。

以上は提供する側の視点ですが、逆に、ユーザー側に立ってみても同じことが言えます。 おまかせはリリース単位が大きいので、アプリがバージョンアップに追従するのも、必然的にたいへんになります。 アラカルトであれば、コンポーネントごとに、インクリメンタルにバージョンアップと検証をしていくことも容易でしょう。

ですから、バージョンアップのしやすさについては、アラカルトの勝ちです。

次のトピックは、陳腐化への耐性です。

アラカルトの特徴として、個々のパーツがダメになったとしても、開発を続けやすいという議論があります。 ダメになったパーツだけ置き換えれば開発を継続できるからです。 もし、利用しているテンプレートエンジンの開発が、ある日突然止まってしまったら? そういう場合でも、別のテンプレートエンジンに差し替えればいいので、ダメージが軽くて済む、というロジックです。

おまかせ環境の場合、ひとつのライブラリへの依存度が極めて大きくなります。 もしそれが陳腐化してしまったら、アプリケーションが取れる選択肢は限られています。

たとえば、Seasar2という一時期国内でかなりの人気を誇ったWebフレームワークがあります。 ですが、残念ながら、2016年に終わりを迎えました。 当時を振り返って、それがいつか終わるとは思いもしなかった、という声もあります。

これは、フレームワークというものと切っても切り離せないリスクだと思います。 おまかせ環境を選択するということは、その環境と運命を共にすることであると言っても、過言ではありません。

陳腐化への耐性という点では、アラカルトのほうがマシなように思えます。

次はコミュニティーという観点から見てみます。

いまどきの開発において、コミュニティーの存在は切っても切り離せません。 それは、おまかせであれ、アラカルトであれ同じです。

ですが、コミュニティーの育て易さ、コミュニティーが協調する力では、 おまかせに若干の分があるのではないでしょうか。 提供する機能が多いほど、ユーザーを獲得しやすくなると考えられるからです。

アラカルトにおいても、たとえばExpressコミュニティー、Reactコミュニティーといったものは存在します。 ですが、Railsコミュニティーほどに集中した力はないのではないでしょうか。

アラカルトは、コミュニティーといっても、最低限の共通基盤しか持ちません。 他のコンポーネントも組み合わせて使っている、雑多なユーザーのあつまりです。 個々のユーザーが使っているものはバラバラです。 つまり、コミュニティーのリソースは、相対的に分断されていると言えるでしょう。

すこし視点をずらして見てみましょう。 いくつかの仮定をしてみます。 開発者の人数と、個々の開発者が貢献できる時間は固定とします。 つまり全体としての開発リソースは固定です。 ですから、各種プロジェクトは有限のリソースを奪いあっている状況になります。

ここで、2つの状況を考えます。 ひとつは、おまかせ環境で、多くのユーザーがだいたい似たようなコンポーネントを使っている状況。 もう一つは、アラカルト環境で、どのユーザーもバラバラのコンポーネントを使っている状況。 これらを比べると、どうでしょう。 開発者のリソースが集中しやすいのはおまかせ環境になるはずです。 ある意味では、開発者のリソースを効率的に活用しているとも言えます。

ユーザーに選択を強制しないのがおまかせです。 そこでは、多くの人が同じものを使っていると想定するのは自然なことです。 選択が強制されるなら、必然的に多様性は高まり、逆に、集中の力は弱まるでしょう。

コミュニティーの力を強めるという点では、おまかせに分があると言えるのではないでしょうか。

次のトピックです。 今度は利用者ではなく、それを開発する側に立って、開発コストという面から見てみます。

インテグレーションコストで話したことや、 バージョンアップのしやすさで話したこととも関係しますが、 開発の大変さはおまかせのほうが上でしょう。

提供する機能がたくさんあるのだから、あたりまえです。 それら個々の機能が互いに連携しあうのであれば、なおさらです。

あるおまかせ環境にコンポーネントXとYがあるとします。 そして、XはYに依存しているとします。 この場合、Yに破壊的変更を加えれば、Xにも修正を加えてテストを行う必要があります。 連携したときに、全体としてうまく動くのかどうかまで、面倒を見なければいけないのです。

対して、アラカルトは気楽なものです。 基本的に、単体でうまくいくかどうかだけを考えればいいわけですから。 さきほどと同様に、XとYがあるとします。 しかし、Yの開発者はXのことを気にせず修正できます。 それはXの開発者が気にすればいいことだからです。

コンポーネントをアプリケーションというひとつのものにインテグレートする苦労は、 利用者側に委ねられているわけです。

また、新規の開発者が参入しやすいのもアラカルトでしょう。 小さいモジュールなら、パッチを送るのが簡単だからです。 フレームワークの全体像を把握したり、波及効果を気にする必要はありません。

開発する側からすれば、気楽に取り組めるのはアラカルトと言えます。

次は、ライブラリの見つけやすさについてです。

おまかせよりもアラカルトのほうが検索がしやすい、という議論があります。 おおきなパッケージよりも小さなパッケージのほうが検索しやすい、という主張です。

たとえば、キーワード補完を実装したいとします。 そこで、これをサポートしてくれるUIライブラリを探しはじめました。

npmで“autocomplete”というキーワードを検索してみます。 すると、

  • autocomplete
  • downshift
  • algoliasearch
  • match-sorter

などが出てきます。

実は、かの有名なjquery-uiにもautocomplete用のウィジェットが含まれます。 ですが、検索では箸にも棒にもかかりません。 “accordion”というキーワードでも同様です。

jquery-uiは雑多なウィジェットの寄せ集めですが、 欲しい機能から、これに辿りつくのは困難ということです。

パッケージに含まれる機能が多くなるほど、特定のキーワードからそこに辿りつくのは難しくなると言えます。 すべての機能をキーワードで的確に表現するのは、不可能とは言わないまでも、かなりめんどうだからです。

単機能で的を絞ったアラカルトパッケージなら、こうはなりません。 その特徴を限られたキーワードだけで表現することも容易になるでしょう。

したがって、ライブラリの見つけやすさはアラカルトの勝ちです。

最後は、ライブラリが対象とする、問題領域の定義について。

おまかせ的な巨大なパッケージでは、 どの機能を入れるのか、あるいは入れないのか、という議論が紛糾しがちです。 本質的には独立した機能をたくさん含んでいるからです。

おまかせでは、何が含まれるべきなのか、という問いへの答えが千差万別で、主観的なものになりがちです。 DHHもエッセイの中でそのことには言及しています。 彼は、好みに合わないなら、その部分を差し替えて使うか、黙って立ち去さるべきだ、という立場を明確にしています。

Node.jsにlodashというパッケージがあります。 これは、単に便利関数の寄せ集めです。 ですから、自分のユースケースをサポートして欲しい、というissueがしばしば上がって来ます。 なにがlodashに入るべき関数で、何がそうでないかは明確ではありません。 ちなみにlodashでは、リクエストのうち+1 voteが多いissueを見て、新機能を決めているようです。

解決すべき問題が小さく限定されていれば、そのような問題は起こりづらいでしょう。 問題領域の定義は、アラカルトのほうが容易であると言えます。

まとめ

以上、おまかせ方式とアラカルト方式に関する10個の側面について見てきました。 まとめます。

おまかせが勝ったのは:

  • インテグレーションコスト
  • 知識・ノウハウの伝搬
  • コミュニティー

アラカルトが勝ったのは:

  • アプリ設計の自由度
  • バージョンアップのしやすさ
  • 陳腐化への耐性
  • ライブラリ開発コスト
  • ライブラリの見つけやすさ
  • 問題領域の定義

引き分けは:

  • 要求されるスキル

という結果になりました。

こうして並べてみると、みんなで同じものを使う大きなものと、 個々人が別々のものを使う小さなものの違いが出ているような気がします。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment