それプログラミングでできますよ

プライベートや仕事で使えるプログラミングや考え方を紹介していきます。

「悪い方が良い」原則について


私が「悪い方が良い」原則を知ったのは、@rui314(Rui Ueyama)さんによるエッセイを読んだからです。まずはそのエッセイを紹介します。



「悪い方が良い」原則と僕の体験談

URL: https://note.com/ruiu/n/n9948f0cc3ed3

Ruiさんは lld v2 というリンカの作者です。さらっと言いましたが、ものすごいことですよこれは!ものすごい人です。


以下、このエッセイをざっくりまとめました。


  • lld v2 のプロジェクトは当初、『良いデザイン』で開発されていた。
    1. リンカの機能を提供するライブラリを作る
    2. プラットフォーム非依存の中間表現にする
    3. プログラムとして頑強でなければならない。そのために入力の正しさを厳しくチェックする。


  • これを実装しようとすると、とても複雑なものになってしまい、プロジェクトはうまく進まなかった。


  • Ruiさんは『良いデザイン』の方針を疑い、あえて『悪いデザイン』でプログラムを書き直すことにした。

    1. 「ライブラリとしてのリンカ」を必要とする人はいないと仮定し、コマンドとして書くことにした。
    2. プラットフォーム非依存の中間表現は全部入りの恐ろしい中間レイヤになるため、冗長ではあるがプラットフォーム依存の実装にした。
    3. 入力を信頼し、チェックすることをやめた。


  • この『悪いデザイン』への方向転換は、以下のメリットをもたらした。
    • 実装が単純になった。
    • 速度が大幅に向上した(v1より10倍ほど高速化)。


  • これがユーザーのニーズを満たしていた。『ユーザーにとってリンカというのはきちんと動いて速ければそれでよい』ものであり、Ruiさんは単にきちんと動いてすごく速いというものを作ったのだった。


  • 『良いデザイン - MIT/Stanfordスタイル』をリーズナブルな範囲で犠牲にし、あえて『悪いデザイン - ニュージャージースタイル』にしたことにより、lld v2 は大きな成功を収めた。



エンジニアであれば、少なからず共感できる点があると思います。
こうやってまとめてみると、確かに『よっしゃ万能で立派なフレームワークつくってやるぜ!』って思ってたら『1つのコマンドを各プラットフォーム向けに作ります。』ってなっているので、当初の崇高な(?)志からは離れますし、反対する人も多かったのが想像できます。

ですがRuiさんの仮説は見事にニーズを的確に捉え、世界中に使われるほどに大成功したという話です。

最後の方にRuiさんが書いている

自分が良いと思うデザインで小さくて実際に動くものを作り、それを次第に育てていくことが大切だ。

という言葉が素敵ですね。
(そしてそれが大きな成功をもたらすこともある)
と、追記してあげたいです。




以上がRuiさんのエッセイ(+私の感想)になります。



話は変わりますが、『Clean Architecture』という本(名著といっても良いと思う)ではアーキテクチャの目的を以下のように述べています。

アーキテクチャの主な目的は、システムのライフサイクルをサポートすることである。優れたアーキテクチャがあれば、システムを用意に理解・開発・保守・デプロイできる。最終的な目的は、システムのライフタイムコストを最小限に抑え、プログラマの生産性を最大にすることである。

どうでしょうか?Ruiさんの lld v2 のケースでは、当初の方針では『システムを用意に理解・開発・保守・デプロイできる』ことは実現が難しかったように見受けられます。となると、やはり『優れたアーキテクチャ』ではなかったのだと思われます。(それを優れたアーキテクチャに近づけたRuiさんは優れたアーキテクトだと尊敬します。)


『Clean Architecture』には、この本の著者の経験談も交えつつ『悪いほうが良い』例が紹介されています。

  • WEBアプリを作る中で、ストレージにはしばらくデータベースを採用しないことにした。
  • 開発フェーズに合わせて、モック → インメモリデータ → ファイルシステム と、ストレージの種類を変えていった。
  • データベースの導入は必要になるときまで、その選択肢を残したままにできた。
  • 遂にデータベースを導入することはなかった。

おそらく業務でエンジニアやっているほとんどの方は、ストレージにはデータベース(RDB/NoSQL)を使うのが常識と思っているのではないでしょうか?ですがこの本には、ファイルシステムという最も単純なストレージを使って、結局それで十分だったという事例が書かれています。


また『Clean Architecture』では、上に書いたアーキテクチャの目的を以下のように言い換えています。

できるだけ長い期間、できるだけ多くの選択肢を残すことである。

これってRuiさんの言う『自分が良いと思うデザインで小さくて実際に動くものを作り、それを次第に育てていくことが大切だ。』と、とても似通った表現というか、根底に流れている想いは同じだと感じませんか。




せっかくなので私の経験談も書きます。 『Clean Architecture』を読んだ後に、私もストレージにはデータベースとファイルシステムを併用することにしました。

データベースとファイルシステムの併用方針


これによって、以下のメリットを得られました。

データベースとファイルシステムの併用によるメリット
  • マスタ系データはファイルシステム
    • バックアップが超ラク(コピーするだけ)
      • 開発環境にデータをリストアすれば簡単に環境を再現できる。
    • スキーマの変更がデータベースに比べて億劫ではなくなった。
    • ファイルシステムの変更監視のライブラリ等を使えばInMemory並のスピードが出る。
  • トランザクション系データはデータベース
    • 検索性能はデータベースが上なので早い。


我ながら併用に舵をきって大正解だと感じました。



と、いろいろと書きましたが、『良いデザイン』というのは誰から見ても見栄えが良いため常識として定着しやすく、常識かのようにいつも使われているデザインは『良いデザイン』の皮を被ることがしばしばあります。
常識を疑い、常に自分たちの目的に近づける方法を模索しなければいけません。


プログラミングでいうと、

『実装の単純さ』は『良いデザイン(常識)』を疑うための理由に十分なりうる。

ということだと思います。

自分は優れたアーキテクトだと信じ、胸張ってこう言いましょう!
× 『まだ決まってません!』← 怒られそう
○『まだ決めなくても良いように柔軟性をもたせています。』




プログラミング以外でも

『〇〇〇』は『常識』を疑うための理由に十分なりうる。

これけっこうありそうな気がします。
しかも『〇〇〇』は一見軽視されていそうなものだったり。




「悪い方が良い」原則


常に意識したい。



Clean Architecture 達人に学ぶソフトウェアの構造と設計【電子書籍】[ Robert C.Martin ]