🐼

ソフトウェア開発は、自作トースターだ!!

2022/06/05に公開

ソフトウェア開発において、英語の良質な記事や本などがすでに大量に和訳されています。しかし、世界中最も母国語話者(出典)の多い中国語から翻訳されたものはまだ少ないでしょう。中国・台湾国内のみならず、シリコンバレーで勤務する中華系のつよつよエンジニアたちの個人ブログを読んで、大変勉強になっています。

drmingdrmerさんの記事「ソフトウェア開発は自作トースターだ!!」を読んで興味深さを感じたため、ぜひ日本語ネイティブの開発者の皆様に共有したいという気持ちを抑えられませんでした。ご本人から許可を得た上に、この記事を翻訳させていただきました。ご参考になれば嬉しい限りです。

また、訳者自身は技術と語学の力不足でどうしても情報ロスが発生するので、中国語読める方は原文を読むのを強くお勧めします。
http://drmingdrmer.github.io/tech/bla/2018/09/27/toaster.html

そうでない方はもしよければ、この和訳版をご覧ください。
さて、始めましょう!


トースターはこのようなものでしょう

原理は非常に単純で、「スイッチで電気を制御し、電熱で加熱する」
これの原理は中学生でも知っているのでしょう。Wikipediaで調べてみたらすぐ出てくるはずです。ただ、

ゼロからトースターを自作するのにどのくらい時間かかるのか?

イギリスのThomas Thwaitesというアーティストの方は数年前に、9ヶ月かかってトースターを作りました。
はい、間違いないです。9ヶ月!
現代社会ですでに確立されたシステムに頼れば、とても簡単なはずですが、
そんなに時間かかった理由は、Thomasは既存部品を一切頼らず、ゼロからすべてを作り上げたためです。
さて、一体どうやってトースターを作ったのを見ていきましょう。
まず、Thomasは市販のトースターを分解してどのような部品があるのを確認して、作業量を見積もりました。

400種類の部品と100種類の材料

ぱっと見て作業量がえぐそうですが、賢いThomasは一連の研究を行うことによって、不要な部品や材料を大幅に削減し、実現できそうなところまで来ました。

  • 銅:プラグ、ワイヤー用
  • スチール:スプリング、グリル用
  • ニッケル:加熱システム用
  • マイカ、プラスチック:ボディーケース用

簡略化された部品のリスト

計画を立てたので、意気揚々とスタート

早速友人にお願いして、鉄鉱山から鉄鉱石を1箱をもらいました。

博物館に冶金学の教科書を探してきた

理論と素材とも揃ったので、作業しましょう!

ドライヤーとゴミ箱で簡易高炉を作った

しかし、鉄のスラグになり、製鉄の計画は失敗しました。
幸いなことに、Thomasは他の方法を早速見つけて...

電子レンジで鉄鉱石を溶かした

30分ほどマイクロ波を受けた鉄鉱石ついに溶けました。
溶けた鉄鉱石でトースターのフレームを作りました。

工場からもらった産業排水の中の溶存銅イオンを置換して銅を得た

プラグ3つを作りました

最後に用意しないといけないものはボディーケースを作るためのプラスチックです。
しかし、30分電話で交渉しても結局油井の作業員を説得できなかったので、石油を取得する計画は失敗しました。
しつこいThomasはジャガイモからプラスチックを取り出すという特許を見つけました

数日後、外に干していたでんぷん質のプラスチックを確認すると...

プラスチックが...ほぼカタツムリに食べられた!?

絶望になりかけたThomasはまた他の方法を探すことになりました。今回はリサイクルセンターにスクラップを大量に手に入れて、打ち砕いて、溶かして、型込をしてようやくボディーケースを作りました。
ここまで、Thomasは全ての材料と部品を揃えて、トースターを組み立てるフェーズに入ります。

数日かかって頑張った結果、こんな感じのトースターを作った

ボディーケースなし版(中の構造ははっきり見える)

続いてエクサイティングなテストタイムだ!!

  • スイッチはないが、まあ、電源入れて動けばよし
  • 絶縁体ではないが、まあ、気をつけて使えばよし

初めて電源を入れたら…

おおよそ5秒経って、トースターが溶けました
はい、見事に溶けました。しかし、Thomasはこのプロジェクトが

大成功

だと思います。その後、The Toaster Projectという本を執筆ました。

トースターのような簡単そうに見えるものでも、自作になるとものすぐ大変です。

使ったものをリストアップしてみよう

(カタツムリに食われたプラスチック、チートで使った電子レンジなどは含めず)

待って、何故わざわざこのお話をするのか

ソフトウェアエンジニアとして、この一連のプロセスは我々毎日の仕事とかなり似ていない?

  • トースター:開発する予定のプロダクト
  • 400種類の部品まで分解:既存プロダクトを研究して、フレームワークのみならずできる限り細部まで理解
  • 5種類の部品まで集約:自分たち開発計画を立て、リリースするのに不要な機能を除く
  • ゴミ箱で製鉄:開発に着手。時々立てた計画が躓いてうまく進まない
  • 油井の作業員を説得できず石油の取得が失敗:どうしても乗り越えられない困難に遭遇、計画を変更しなければならない
  • 電子レンジで鉄鉱石を溶かす:代替案を探す途中、使いやすいツールを発見
  • スイッチがない:さまざまな困難を乗り越え、ver1.0を開発した。UIが醜くて機能も欠落
  • 絶縁でない:安定に動作するプロダクトではないが、なんとなく動ける
  • 5秒で溶ける:リリース初日に落ちる

こう見ると、ソフトウェア開発はくだらなさの極みでしょう?

認めたくないですが、
ほとんどの場合は間違いないです。

  • 90%のプロジェクはこのプロセスで進んでいる
  • 90%のプロジェクトは最終的に失敗する
  • 90%のコードの生存期間は3年以下

ただ、問題は人ではない

Thomasのお話を振り返ってみれば、彼はとっても賢くて、資料を調べて、さまざまな方法を試しました。しかし、それでも9ヶ月かかって、全く使えないトースターしか作れなかったです。
なぜでしょうか?(優秀なつよつよエンジニアでも良いプロダクトを作れないのはなぜでしょうか?)
気づいた方もいると思いますが、このお話はかなり厳しい制約があります。

ゼロから作る

The Toaster Projectはゼロから作るプロジェクトのため、人類が今まで蓄積してきた科学技術・ツール群の力を一切借りることができないという制約があり、全てのことをThomas自らの力で完成させないといけません。(チートで電子レンジを使ったことを一旦忘れましよう)

もし「ゼロから作る」という前提がなかったら、各種ツールを利用して状況は一変するはず

  • 標準化されたネジ
  • 高品質・信頼性のあるワイヤー
  • 3Dプリンターやプラスチックの金型
  • プライヤー
  • スパナ

などのツールを利用し、信頼性の高い部品を確保することによって、部品間の標準化されたインターフェースが保証されます。ちゃんとした使えるトースターを作るのはもう難しいことではないでしょう。

このような完備している「ツール群」があると、ほぼトースターを使ったことがない人でも(例えば筆者)簡単に使えるトースターを作れるでしょう。標準化されたネジ、高品質のプラスチック、高品質のワイヤー、標準化されたインターフェースのあるスイッチは簡単に買えるからです。

高品質・信頼性のある部品のおかげだ

部品がちゃんと動いているのかを考える必要が完全になくなり、組み立てに集中することができます。
先程の話に戻りますが、なぜ優秀なつよつよエンジニアでも良いプロダクトを作れないのでしょうか?理由は明らかで、信頼できる「完備したツール群」が欠如しています。

完備したツール群

ソフトウェア工学は人間社会と同じく、ほとんどの人は直接「トースター」のような最終製品を作らないはずです。

ほとんどの人の仕事は他人をサポートするための部品をひたすら作ること

  • 国際基準で定められたネジの太さ、硬さ、間隔など
  • 製鉄所で生産された高品質の鋼線

これらのサポートがあると、優れたプロダクトを作ることが可能になります。
もしプロダクト開発を担当している人が自ら全ての基礎ツールと部品を用意することになると、数十、いや、数百の未知な分野に挑まなければなりません。人間の時間と体力は限られているので、必然的に不良品が作られてしまいます。品質の良い部品がないと、最終プロダクトの品質も保証できません。

トースターのプロジェクトと同じように、ソフトウェア開発の成功か否かは、エンジニアがコアビジネスロジックに全集中できるか、つまり、エンジニアたちを支える充実したツール群が存在するかによって決められます。

今、我々はこのようなツール群が必要だ

市場競争を勝つには、巨人の肩に立って、もう一歩前に目指さないといけません。
コミュニティの中に公開されているOSSや、市販されているソフトウェアは、ファーストステップとしては有効な手段です。これらのソフトウェアのおかげで高いレベルにより早く到達できます。しかしその反面、これらのソフトウェアを利用している時点、すでに時代に遅れています。なぜかというと、ソフトウェア業界の流れが非常に速いので、誰も競合に負けないように自分たちの武器を磨き続けています。

  • 平凡なソフトウェアは、既存ツールの力を借りる
  • 優秀なソフトウェアは、既存ツールをベースにして、新しいものを創出する

市場競争において、他人が優れたツールを作ってくれるのを待つのでなく(誰でも入手できるものは凡庸そのもの)、我々の手で前代未聞のソフトウェアツール群を構築しなければなりません。ここまではセカンドステップです。自分あるいは仲間と一緒に自分たちのツール群を築き、安定させ、十分に進歩させることで、次の「肩」になるのでしょう。その肩に立ち、手を伸ばせばより高い場所に触れることができるのです。

会社とは何か

  • 外部から見ると、会社はこのようなところ:人々を集めて、同じ目標を目指して頑張る。
  • 内部から見ると、上記の記述は会社の本当の役割と意味を説明するのに少し物足りないです。

共通した目標以外に、会社はプラットフォームのような存在で、このプラットフォームにいる全ての人が簡単に他人の力を借りることができ、もっと高いところ到達します。

しかし、同じ職種間のギャップは気づきにくいため、相互サポートは若干難しくなるのです。ホモゲネート化になっているため、お互いにサポートできる箇所を探すのに深く観察する必要があります。
ただ、ITは古くからある産業と異なり、情報の複製や経験の複製はほとんどコストかからず、成果はゼロコスト(物理的なゼロコスト)で他人に伝えることができます。

なので、このメリットを最大限に生かすのだ

良い会社とは、共通の目標を待つ人々にアツイ環境を提供し、一人ひとりの知識を溶かして溶岩となり、より高い峰を築いていくところです。
我々の肩こそ巨人の肩、我々の肩でなければなりません。
自分の肩を高め、安定させ、他人に支える肩を提供するのは我々の責任です。一方、誰でも仲間の肩を掴めて次のステップ目指せる環境を提供するは会社の責任です。
開発においては、我々ができることは、持っている経験や知見などで標準化されたツール、部品を作成し、最終的にプラットフォームを構築します。そうすると、次のThomasはきっと素早く品質の良いトースターを作れるのでしょう。

社内の理想的なツール群の姿

簡単に言うと、会社の発展は小さいピラミッドから大きなピラミッドへ建て替えるプロセスです。
最初の複数のツールで一つのプロダクトを支えるから、複数のツールで複数のプロダクトを支えることに進化します。

左図のように、初期は3つのプロダクトにそれぞれ必要なツールを3つずつ(重複あり)をそれぞれ保守します。理想としては、右側のように5つのツールで3つのプロダクトを支えることです。達成できれば、必要な労力は9単位から5単位になり、ある意味では効率は5単位から9単位に向上することになります。

品質の担保

相互サポートというのは、使えるモノを他人に提供することです。信頼できるモノでなければなりません。
規格にぴったりと合うネジのように、カップリングがタイトで、緩む心配が一切なし、再び安心に利用できます。この「心配無用」こそ効率の向上に繋がります。なぜなら、ネジを利用する人は本来やるべきことに集中できるからです。
品質は再利用の前提条件であり、高品質な部品は効率の向上、低品質の部品は故障率の上昇につながります。だからこそ、品質がツールを体系化するための基礎となります。
品質を確保することの優先度を一番高くすべく、そうでなければ、ゴミを作るために命を燃やそうとしていることになります。社員の時間の無駄遣い、会社が成長する機会を失うほかならないです。
初期のインターネット上にあるプロダクト(品質問題をカスタマーサービスで補うことが多い)の影響もあり、業界では品質への関心が低かったです。なぜなら、品質低下の影響が出るまでに数ヶ月から1、2年かかるに対して、90%のコードの寿命は2年未満です(それ以下のものもあるかもしれません)。
一般的に、短期的な品質の低下は、オペレーションやカスタマーサービスで補うことができます。
効果出るのが早いため、短期的な利益がいつも好まれ、長期的な利益が無視されやすいです。徐々にオペレーションやカスタマーサービスに費やすコストが増加し、最終的にオペレーションやカスタマーサービスにかかる100%のコストをかけても10%の利益しか生まれない日がやってきます。

品質はどうやって測る?

品質の担保するため、そもそも品質とは何かを理解する必要があります。
品質というものは、非常に多くの側面があるため、たとえば、1000個の細部がよくできていたとしても、たった一つの欠落でプロダクトの品質を台無しにしてしまうこともしばしばあり、簡単に測定できるものではありません。
プロダクトの品質を測るには、一つも欠けることなく細部まで測らなければなりません。例えば

この例を見ればわかると思いますが、KPIのようなものはプロダクトの品質向上にあまり繋がらないです。初期段階はいくつの優れた機能が点在すれば十分だったので、品質はそれほど重要ではありませんでした。しかし、プロダクトの完成度が高まってくると、細部は極めて重要になり、最も欠如なところがプロダクトの品質を左右するようになります。
ソフトウェアの品質問題を短期的に測定する良い方法は存在しないと断言できますが、長期的には、コードの「増加率」と「廃棄率」という二つの指標で、比較的簡単に測定できます。

品質測定の例: nginx

例えばすでに安定に動作しているnginxの13年のgit履歴を分析すると、コードの増加率は201%、廃棄率は48%です。

  • 13年前→5年前 増加率129%、廃棄率39%
  • 過去5年間 増加率31%、廃棄率11%
  • 過去1年間 増加率4%、廃棄率わずか1%にとどまっている

ご覧のように、初期は大規模な開発期間であったため、しょっちゅう多くの問題が見つかりました(廃棄率39%)最近だと、小さいな修正はありますが、安定に動作するプロダクトが仕上がっていることがわかります。

安定に動作するソフトウェアの基準

安定に動作するソフトウェアは下記の基準を満たしていることが望ましいでしょう。

  • 年間廃棄率10%未満である
  • 年間成長率は廃棄率よりはるかに高く、例えば10倍

短期的に見ると、増加率が廃棄率の10倍程度であれば、非常に健全なソフトウェアとも言えるでしょう。

  • 短期間というのは、非常に短い期間という意味ではなく、少なくとも一つのフィードバック周期。例えば、テスト・レビューの周期、あるいはPOC・フィードバック・デバッグの周期。
  • この二つの指標はKPIなどの評価基準ではない。KPIとして使ってしまうと、完全に本末転倒

品質の向上

ここまでくると、品質向上の為のアプローチが「簡単」になるはずです。
下記のことを考えながら、削除されたコードをレビューしてみましょう。

  • なぜ削除したのか
  • 当時十分に検討しなかったことは何か
  • 何が漏れているのか

長期的なアクション:ツール群の構築

ビジネスロジックと直接関連しているコードは、最上位にあるため、品質にほとんど影響を与えませんが、この部分が依存している下位のコードは非常に重要な役割を担っています。

筆者たちのコードを見てみましょう。

  • 8年前、本稼働したばかりの頃、イテレーションが早く、今と比べるとコードの58%が廃棄された
  • 昨年から今年まで、状況が一変し、増加率40%、廃棄率9%にとどまっている。
  • 7年前の1年間は:増加率28%、廃棄率16%
  • 8年前の1年間は、増加率44%、廃棄率13%

その大きな要因は、ビジネスの変化によるものです。頻繁な修正は品質保証の障害となるため、プロダクトの品質を保つため、一部のツールをビジネスプロジェクトから切り離します。目的は2つ

  • 独自にテストを行うことができ、品質確保が簡単になる
  • 簡単に共有可能

筆者たちが実装した2つのツール直近一年間の変化は

この二つのツールキットは、現在我が社の4つのプロダクトに利用されています。

  • ストレージ(S2)
  • コールドデータ(EC)
  • エッジコンピューティング(Edge)
  • コンフィグセンター (Config-Center)

一つのツールが複数のプロダクトに対応できるようになり、これらツールは安定に動作しているので、ビジネス展開は非常に効率的になりました。
ECを始めた当初、わずか40日で本稼働できたのは、経験とこの二つのツールのお陰でです。

  • 分散型redisクラスタ。
  • 分散型トランザクション管理
  • メタデータセンター

などのモジュールの実装(ロジック、メンテナンスツール、ログ管理などを含む)は、積み重ねたこの二つのツールのお陰で3、4人日程度で完了しました。(ツール群がなければ、Thomasのように、9ヶ月くらいかかるでしょう)

まとめ

繰り返しとなりますが、
我々の肩こそ巨人の肩、我々の肩でなければなりません。
自分の肩を高め、安定させ、他人に支える肩を提供するのは我々の責任です。一方、誰でも仲間の肩を掴めて次のステップ目指せる環境を提供するは会社の責任です。

最後に

エンジニアの皆さん、品質の良いトースター作れますように!!

Discussion