コードは「何をするか」しか教えてくれない

Marc Brooker
AWSエンジニア。Lambdaやその他のサーバーレスプロダクトのエンジニアリングをリードしています。
この記事は、著者の許可を得て配信しています。
http://brooker.co.za/blog/2020/06/23/code.html

コードは、それが何をするかを示しています。それはコンピュータにとって重要なことです。コードはコンピュータに何かをしてもらうための方法だからです。コードを修正したりデバッグしたりする必要がない限り、人間にとっては問題ありません。しかし、すぐに問題は発生します。基本的に、デバッグとは、プログラムが行うべきことに合わせて、プログラムが行うことを変更することです。プログラムが何をすべきかを私たちが知っている必要がありますが、それはコードには書かれていません。時には、それが簡単な場合もあります。プログラムはクラッシュしますが、クラッシュはすべきことではありません。このような些細なケース以外では、目的を見つけるのは難しいのです。

分散システムのプロトコルを構築する場合のように、何をすべきかが微妙な場合のデバッグは特に困難です「Millions of Tiny Databases」という論文では、次のように述べられています。

私たちのコードレビュー、シムワールドテスト、設計会議では、Javaコードや書面によるコミュニケーションの曖昧さを解決するために、私たちのプロトコルのTLA+モデルを頻繁に参照していました。

問題は、実装(Physaliaの場合はJavaコード)がプロトコルの実装が不完全になってしまうことと、プロトコルの実装が過度に指定的であることです。指定的になりすぎているのは、完全に指定的である必要があるからです。コンピュータはそれを要求しますが、それでもなおプロトコル自体には多少の余裕とゆとりがあります。また、仕様では気にすることができない低レベルのパフォーマンスの問題などに対処しなければならないため、過度に指定的になっているのです。

ArrayListにそれらの値が入っているのは、実際には順序が重要だからなのか、それともO(1)ランダムシークが重要だからなのか、それとも何か他の理由があるのでしょうか?単に書きやすかっただけだからなのでしょうか?それを変更するとどうなるのでしょうか?

分散プロトコルのキャッシュ性に欠けていますが、ビジネスロジックコードにおいては、この種の問題は数多くあります。コードはビジネスロジックを過剰に指定し、不正確に指定します。これを書くように促されたのは、@mcclure111さんのツイートを見たからです。まさに彼女の指摘は的を得ています。

「どのクセに負荷がかかっているのかが分からない」というのはコードの主な問題です。覚えているかもしれないし、推測できるかもしれないし、第一原理からこの問題を解くことができるかもしれないし、気にしない人もいるかもしれませんが、どれも時間がかかるし、エラーを起こしやすい。これについては、どうしたらいいのでしょうか?

デザイン・ドキュメンテーション

ドキュメンテーションは全くかっこいいものではありません。ほとんどのソフトウェアエンジニアは、学校を卒業したときに、ドキュメンテーションは自分より下のレベルの人がする仕事(テックライターの仕事)だと思っているようです。また「Fortran(1950年代に誕生した、世界初の高級プログラミング言語)と同じくらい古臭い」という変な話を某SEの教授がしていたという話もあります。これは理解できる部分もあります。私自身のソフトウェア工学のコースでは、UMLでの実装を丹念にドキュメンテーションすることに重点を置いていました。それ以外には、ドキュメンテーションについての言及はありませんでした。UMLでソフトウェアを書き直しても、基本的には何の役にも立ちません。私は、ドキュメンテーションは不要な暇つぶしだと思って学位を取得しました。アジャイルソフトウェア開発宣言でさえ、私に同意してくれました。

包括的なドキュメンテーション全体で機能するソフトウェア

後になって分かったことは、システム開発中の意図や意思決定をコード化したデザインドキュメンテーションが、短期的にはチームを成功させ、長期的には人を成功させるのに役立つということです。すべてを頭の中に収めることから解放され、忘れていた事実を後で再発見できるという自信がついたことで、より速く動けるようになりました。チームにも同じことが言えます。

成功しているチームは、設計の背後にある「何を」と「なぜ」だけでなく、「どのように」決定したのかをドキュメンテーションするということを行っています。デバッグのために、あるいは要件の変更に対応するために、システムに変更を加えるときには、これらのドキュメントは非常に貴重なものとなります。そもそもなぜそのような状態になっているのかが分からないと、変更を加えても安全なのかどうかを判断するのは難しいからです。皆さんは欠陥を持つ人間であり、どのようにして決定に至ったかを理解することは、その決定が変な変更だったり、驚くべき決定であったりするときにその背景を知るのに役立ちます。

このドキュメンテーションのプロセスを負担に感じる必要はありません。役に立たないと思うのであれば、骨の折れるER図を描く必要はありません。UMLも完全に無視したほうがいいでしょう。その代わりに、システムをできるだけ明確に、簡潔に記述してください。そのためには、自分のチームのためにRFCテンプレートを作ることから始めるとよいでしょう。SquareSpaceのテンプレートが妥当だと思います。いくつかのデザインはそのRFCフォーマットに合うものもあれば、そうでないものもあります。できればナラティブ(誰にでも伝わる、説得力のあるストーリー性のある)なものがいいでしょう。

それから、ドキュメントは必ず保管しておくようにしましょう。どこか安全な場所に保管してください。酢に浸して自分の胸元に縛り付けておくのもいいかもしれませんね!システムを維持する必要がある人が、それを見つけられるようにしておきましょう。それがあればシステムの管理者が履歴を洞窟探検しているときに、図書館に来ているように感じるようにしてくれます。 自分がララ・クロフト(ビデオゲーム『トゥームレイダー』シリーズや、それを原作とする映画に登場する架空のイギリス人。同作の主人公)のようだと感じさせないようにしてくれます。

私は計画的設計や、事前の大規模設計(Big Design Up Front:BDUF⁠)を提唱しているわけではありません。私たちがプロジェクトについて学ぶ最も重要のほとんどを実装中に学びます。最も重要なことのいくつかは、実装が完了してから何年も経ってから知ることになります。デザイン・ドキュメンテーションは、一度だけの静的な先行成果物ではなく、継続的なプロセスなのです。最も重要なことは、デザイン・ドキュメンテーションは、悪いアイデアにコミットするものではないということです。間違っている場合は修正して前に進みます。ドキュメンテーションは悪魔との取引ではありません。

コメント

コメントのようにプログラマの炎上を招く話題はほとんどありません。コメントは馬鹿げているとか、幼稚だとか、ああやって難解で複雑なコードを書いて、自分がどれくらい男らしいかを誇示したいだけなんだ、などと言われます。書くのが大変なら、読むのも大変なはずです。結局のところ、あなたはコードのジェームズ・ジョイス(20世紀の最も重要な作家の1人と評価されるアイルランド出身の小説家、詩人。難解な小説を書く)なのです。

そんな馬鹿げたことはさておき、@mcclure111さんのスレッドに戻りましょう。

コメントは、プログラミング言語にはない方法で、作者のインテントをコードにエンコードすることを可能にしてくれます。タイプ、トレイト、インターフェイス、変数名はコードにインテントを入れていますが、完全には入れていません(型システム過剰主義者の皆さん、聞いていますか?)。これらと同じようなことで、インテントの不足を伝えるようになりますが、不完全なものです。RandomAccessArrayList の比較を考えてみてください。特に、コードへの翻訳で意図が失われている場合や、実装制約によって設計の意図が隠されている場合には、コメントがしっかりされたコードは、作者のインテントを明確にする必要があります。デザインドキュメントにリンクするコードコメントは特に有用です。

言語によっては、他の言語よりもコメントが必要なものもあります。SQLのように、実装の詳細の背後にある設計のインテントがほとんど常に不明瞭になっているものもあります。

正式な仕様

Who Builds a House Without Drawing Blueprints?(設計図を描かずに家を建てられるか?)」で次のようにLeslie Lamport氏は書いています。

仕様書の必要性は、2つの観察から導かれます。1つ目は、何をしようとしているのかを考えてから実行するのが良いアイデアであり、漫画家のGuindon氏が書いたように、「書くということは、自分の考えがどれだけ杜撰であるかを教えてくれる自然な方法である」ということです。

2つ目の観察は、良いプログラムを書くためには、コードレベルの上で考える必要があるということです。

私は、ナラティブなライティングによる非公式な仕様から TLA+ による形式的な仕様書まで、仕様書があることで、プログラムをより速く書き、ミスを減らすことができることに気がつきました。Lamport氏は形式な仕様書の価値の重要な部分を見逃していると思います。それは、素晴らしいコミュニケーションツールです。私がこれまでに構築した中でもとても厄介なシステムを開発しながら、多くのコメントが付けられた形式仕様書が非常に有用なドキュメントであることに気付きました。仕様書の言語はすべてインテントについてのものであり、インテントと実装を明確に分離することを容易にしているものもあります。

繰り返しになりますが「Millions of Tiny Databases」という論文からの引用です。

私たちはAmazonでTLA+を広く利用していますが、Physaliaの開発において非常に有用であることがわかりました。私たちのチームは3つの方法でTLA+を使用しました。プロトコルを深く理解しているかどうかを確認するためにプロトコルの仕様書を書くこと、TLCモデルチェッカーを使って仕様書の正しさや活性度をモデルでチェックすること、そして分散プロトコルのドキュメントとして機能するように広範囲にコメントされたTLA+コードを書くことの3つです。これら3つの用途のすべてが付加価値をもたらしましたが、TLA+の役割は、(TLCを介して)自動的にテストされ、非常に正確なプロトコルドキュメンテーションのためのフォーマットのようなものとして、おそらく最も有用でした。

正式な仕様書は優れたドキュメンテーションになります。デザインドキュメントのように、それは不変のアーティファクトではなく、問題について学んだことを反映したものです。

まとめ

長持ちし、メンテナンス性の高いシステムを構築するためには、コンピュータとのコミュニケーションだけでなく、空間での人とのコミュニケーション、そして未来の自分との時間的なコミュニケーションが必要となります。その中で、設計のインテントを伝え、記録し、インデックス化することは重要な部分となります。そのための時間を作らないと、後々後悔することになります。

脚注

1.アジャイルな人たちにはありがたいことに、包括的なものは負荷がありそうです。


コメントを読む

新着ピック  






















新着ニュース

直近半年で半数以上持ち帰り売上増、今後も継続予定 コロナ禍に開始4割/クックビズが飲食店74店に調査

Juliaで役に立つ豆知識 - Qiita

[無料で簡単]RailsアプリをHerokuで公開する方法 - Qiita

Goで画像をクリップボードに保存、読み取るライブラリを作った - Qiita

JuliaでPlotsするよ - Qiita

本家Rustコンパイラのソースを読もうとしてみる(1) - Qiita

【Streamlit】JavaScriptが嫌いだからPythonだけでWebアプリをつくる - Qiita

いまさら聞けない「VoIP」「VPN」「Wi-Fi」「WAN」とは?

2018年8月9日、60歳以上なら通話が無料になる「かんたんスマホ」(705KC)が発売されました:今日は何の日? - Engadget 日本版

コロナ重症者のリハビリ、入院中に始めて早く復帰

オンライン・バーチャル展示会サービス「DX EXhibition」。リアル展示会のブースやショールームを まるごとバーチャルに変換する「DX EXhibition ARCHIVE」を販売開始。 | Ledge.ai

マーベル本社の壁画として、ヒーロー35名が集結! 圧巻の制作過程を公開

Uber Eatsはライドシェア事業より大きくなったが、まだ利益は出ていない | TechCrunch Japan

Microsoft、「スマホ同期」の最新版を発表 - PCから個別アプリを制御可能に

新型コロナで露呈したAIの限界と、それを乗り越える方法

ソロキャンにいいね! 薄さ7mmで保管できる超コンパクトな焚き火台「FlexFire」を使ってみた

人気声優・緑川光が日替わり豪華ゲスト声優と8夜連続で対談生放送決定【ニコニコネット超会議2020夏】 - ライブドアニュース

国連「古いエアコンをどうにかしないと人類は自分自身を蒸し焼きすることになるよ」

仮想プレゼンツールmmhmmのベータ2が登場、二人同時プレゼン操作が可能に | TechCrunch Japan

MediaTek、Intelと共同開発したPC向け5Gモデム「MediaTek T700」発表 - Engadget 日本版

記事をPICKする
appstore
googleplay
会員登録
Register
記事をPICKする

会員登録すると、もっと便利に利用できます。