5 ポイント 投稿者 GN⁺ 2025-06-18 | 1件のコメント | WhatsAppで共有
  • 複雑性は開発において最も危険な要素である
  • 真の効率性は「80/20ソリューション」など、複雑性を避ける実用主義的なアプローチから生まれる
  • テストとリファクタリングについて、バランスが取れた柔軟な姿勢を保つことが重要である
  • ツール活用および読みやすく保守しやすいコードを書く習慣を採り入れることを強調する
  • 過度な抽象化やトレンドを警戒し、単純さを追求する姿勢を勧める

はじめに

  • この記事は、長年ソフトウェアを開発してきた中で経験から学んだことを整理した、グラグ・ブレイン開発者の考えのまとめである
  • グラグ・ブレイン開発者は自分をそれほど賢いとは思っていないが、長いあいだプログラミングを続ける中で多くを学んだ
  • 他の人たちが失敗から学べることを願い、わかりやすくて面白い形で気づきを共有している
  • 複雑性こそが開発人生における最大の敵である
  • 複雑性はコードベースにひそかに入り込み、最初は理解しやすかったコードさえ次第に修正不能な状態へと追い込む

複雑性の悪霊への対処

  • 複雑性は見えない霊のように音もなく染み込み、プロジェクトマネージャーやグラグではない開発者には認識されにくいことが多い
  • 複雑性を防ぐ最善の方法は「ノー」と言うことである
    • 「この機能は作らない」
    • 「この抽象化は導入しない」
    • もちろん、キャリアの面では「イエス」と叫ぶほうが得なこともあるが、グラグ・ブレイン開発者は自分に正直な選択を重視する
  • 条件によっては妥協(「ok」)も必要であり、その場合は80/20ソリューション(パレートの法則の適用)で問題を単純に解決するやり方を好む
  • プロジェクトマネージャーにすべてを話さず、実際には80/20方式でやり切るのも賢い戦略である

コード構造と抽象化

  • コードの適切な単位(カットポイント)は時間が経つにつれて自然に見えてくるため、初期段階の抽象化は避けたほうがよい
  • 良いカットポイントは、システムのほかの部分とのインターフェースが狭いのが理想である
  • 早すぎる抽象化の試みは失敗しやすく、経験豊富な開発者はコードの形がある程度固まってからゆっくり構造化を試みる
  • 経験の浅い、あるいは「ビッグブレイン」な開発者は、プロジェクト初期に過剰な抽象化を試み、保守の負担を残しがちである

テスト戦略

  • テストに対するこだわりとバランスが重要である
  • プロトタイピングの後、コードがある程度固まってからテストを書くことを好む
  • ユニットテストは初期に活用するが、実際には中間段階(統合テスト)が最も大きな効果を見せる
  • E2Eテストも必要だが、多すぎると保守不能になるため、本当に必要な経路だけを少数に絞る
  • バグ報告があったときは、必ず再現テストを追加してからバグを修正する

プロセス、アジャイル、リファクタリング

  • アジャイルはグラグ開発者にとって悪くはなく、最悪でもないが、「アジャイル・シャーマン」へ過度に期待するのは危険である
  • プロトタイピング、ツール、良い仲間のほうが実際にはより重要な成功要因である
  • リファクタリングも良い習慣だが、大規模で無理のあるリファクタリングは危険である
  • 複雑な抽象化を無理に導入することが、かえってプロジェクト失敗を招く

保守、完璧主義と謙虚さ

  • 既存システムを理由もなく作り直すのは危険であり、「なぜ存在するのかわからない構造」をむやみに消すのは良くない習慣である
  • 完璧なコードを夢見る理想主義は、現実にはたいてい問題を引き起こす
  • 経験を積むほど、「動いているコードは尊重すべきだ」と身をもって感じるようになる

ツールと生産性

  • 優れた開発ツール(IDEのコード補完、デバッガーなど)は生産性を大きく高めるため、深く理解することが重要である
  • 型システムの本当の価値は「自動補完」とミス防止にあると強調し、過度な抽象化やジェネリクスはむしろ危険だとする

コードスタイルと重複

  • より読みやすくデバッグしやすいコードのために、条件式を複数行に分けるようなスタイルを勧める
  • DRY(Don’t Repeat Yourself) 原則は尊重するが、重複コードを無理に排除するよりもバランスが重要だと強調する
  • 単純な繰り返しのほうが、複雑なDRY実装より優れている場面も多い

ソフトウェア設計原則

  • SoC(関心の分離)原則よりも行動の局所性を好み、「その振る舞いをするコードは、そのオブジェクトの中にあるほうが保守しやすい」と主張する
  • コールバック/クロージャ、型システム、ジェネリクス、抽象化などは、少量を適切に使うべきだと警告する
  • クロージャの乱用は、JavaScriptで「コールバック地獄」を生みかねない

ロギング、運用

  • ロギングは非常に重要で、主要な分岐ごとに残し、クラウド環境ではリクエストIDなどで追跡できるように構成する
  • 動的ログレベルやユーザー別ログを活用できれば、運用中の問題追跡に大きく役立つ

並行性、最適化

  • 並行性については、できるだけ単純なモデル(状態を持たないWebリクエスト、分離されたワーカーキューなど)だけを信頼する
  • 最適化は、実際の性能プロファイルデータを確保してから行うことを勧める
  • ネットワークI/Oなどの隠れたコストに注意すべきであり、単にCPUの複雑度だけを見るのは危険である

API設計

  • 良いAPIは使いやすいものであるべきで、複雑すぎる設計や抽象化は開発者体験を損なう
  • 「ユースケースに合った単純なAPI」と、「複雑なケースにも対応できる階層的なAPI」という構造を勧める

パーサー開発

  • 再帰下降パーサーは学術界では過小評価されがちだが、実際のプロダクションコードには最も適していて理解しやすい方法である
  • これまでの多くのパーサー開発経験では、ツール生成のパーサーは成果物が複雑すぎて、問題解決の面ではむしろマイナスになることが多い
  • おすすめ書籍として『Crafting Interpreters』を最高の一冊に挙げており、実務的な助言が多く含まれている

フロントエンドと流行

  • モダンフロントエンド(React、SPA、GraphQLなど)は、かえって複雑性の悪霊をさらに呼び込み、不必要な場合が多い
  • Grug本人は、htmxやhyperscriptのような単純なツールで複雑性を減らすやり方を好む
  • フロントエンドでは絶えず新しい試みが行われているが、既存アイデアの繰り返しも多い点に注意が必要である

心理的要素、インポスター症候群

  • ほとんどの開発者は「自分が何をしているのかわからない」と感じることが多く、FOLD(Fear Of Looking Dumb) 現象から自由になる必要がある
  • シニア開発者が「これは自分にも難しい、複雑すぎる」と公に言えば、ジュニア開発者も肩の力を抜ける
  • インポスター症候群はよくある感情であり、十分に学びながら成長していけると励ましている

結論

  • プログラミングでは複雑性を常に警戒すべきであり、単純さを保つことが成功する開発の核心である
  • 経験、ツールの効果的な活用、謙虚さ、実際に動作するコードへの敬意が、長期的に効率的で価値ある開発へとつながる
  • 「複雑性はとても、とても悪い」—この一文を常に覚えておくべきである

1件のコメント

 
GN⁺ 2025-06-18
Hacker Newsの意見
  • 私は優れたデバッガの価値をいくら高く見積もっても足りないほどだと思っているし、実際それ以上にすごいと感じている。小さなスタートアップでも有名なビッグテックのチームでも、チームでデバッガを使っているのが自分だけということがよくあった。実際、いまだに多くの人が print 文でデバッグしている現実を見てきた。自分のワークフローを同僚に伝えようとしても反応がない。システムを理解するための最良の出発点はまさにデバッガだという点には同意する。テスト中に興味深いコード行で止めてスタックを見るのは、頭の中でコードを追うよりずっと簡単だ。デバッガの使い方を身につけておけば、本当にささやかな超能力を得るようなものだ。できるならぜひ一度試してみてほしい
    • 本当はちゃんとしたデバッガを使いたいが、大企業でしか働いてこなかった立場からすると、現実的には不可能な状況だった。マイクロサービスのメッシュアーキテクチャではローカルで何も動かせないし、テスト環境でもステップデバッガを接続できないよう設定されていることがほとんどだ。だから print デバッグが唯一可能な選択肢になる。ログシステムにまで問題があったり、プログラムがログを出力する前にそのままクラッシュしたりすると、print すら使えない状況になる
    • この話題については数年前に良い議論があった。Brian Kernighan と Rob Pike の名言があるが、二人とも若い開発者ではない。"私たちは stack trace や変数の値をいくつか確認する程度を超える目的ではデバッガを使わない。複雑なデータ構造と制御フローのせいで、細部に閉じ込められやすいからだ。自分でプログラムについて頭でもっと考え、ところどころに print による出力や self-checking code を入れるほうが生産的だ。print を入れるほうが、デバッガでステップ実行するよりずっと速い。さらに、print のコードはプログラムに残るが、デバッグセッションは消えてしまう。" 私もこの意見に同意する。開発プロセスの大半では、print→仮説→実行のループのほうがずっと速く問題解決につながる。頭の中でコードを「実行してみる」のではなく、コードフローについてすでに動作モデルがあるので、print が間違った出力を見せればたいてい素早く実態を直感できる。関連リンク: The unreasonable effectiveness of print debugging
    • Linux 系で printf デバッグが常に一般的だった理由は、GUI ベースのデバッガを信頼できない環境だったからだ。Linux の GUI はしばしば不安定で信用できない。私がデバッガをちゃんと使い始めたのも、(1) Windows では GUI はよく動くが CLI がしばしば壊れるときであり、(2) print デバッグのコードが誤ってバージョンに入り込んで問題を起こした経験を何度もした後だった。その後 CLI デバッガでもいろいろ冒険したし、Junit+デバッガ(Eclipse など IDE ベース)で実験的なコードをその場で書きながらテストとして残すプロセスは、Python REPL と同じくらい便利だと感じた。ただし、デバッガを環境に合わせてセットアップする初期投資は必要だ
    • 自分のコードではデバッガを使いやすいし本当に好きだ。けれど、デバッガが自分の書いたコードではなくライブラリやフレームワークの内部深くに入っていくと、自分もすぐに道に迷って嫌になる。こういうフレームワークやライブラリは何十万時間もかけて作られているので、自分のレベルではすぐ理解の範囲を超えてしまう
  • Carson教授、もしここをご覧になっていたら、心から感謝を伝えたいです。大学の頃は、なぜ HTMX を学ぶのか、なぜあれほど情熱的だったのか理解できませんでしたが、数年後にようやく本当に分かりました。HTML over the wire こそが本質です。Staff Ruby on Rails Engineer として働きながら、Hotwire でも教授の仕事を何度も目にしましたし、時々 GitHub や Hacker News で活動されているのを見ると本当に驚かされます。いつもプログラミングコミュニティの光のような存在です。深い敬意と感謝をお伝えします
    • ここで胸が熱くなるのは私だけじゃない、感動的だ
    • HTMX ってただのミームじゃなかったの? Poe’s Law のせいで本気なのか分からない
  • この文章には本当に名言が多いが、私はマイクロサービスの話がいちばん好きだった: "grug は、大きな脳でもシステムをまともに分解するのが難しいのに、そこへわざわざネットワーク呼び出しまで追加する理由が分からない"
    • システムを部品に分ける方法として API にすることしか知らない人たちもいる。API として公開されていなければ、ただ理解不能で再利用もできない不透明なコードだと考えている
    • いろいろな理由でマイクロサービスが実用的な場合もあって使われているという点は、少し残念でもある
    • ちょっとした Web アプリひとつにフォームが5個あるだけでも、2人だけの小規模な開発チームがそれを「マイクロサービス」構成(データベース共有、API 管理、キュー経由のバッチ処理、メール通知、独自 Observability プラットフォーム追加など)で複雑化させるのを見続けてきた。そして結局、普通のフォームまで SPA にして、「そのほうが簡単だから」と言う。今では「アーキテクチャ」や「パターン」が、役に立たない開発者たちの仕事を作るためのものだと理解している。もしそういうものがなければ、「サンドイッチ一切れでもくれるなら JavaScript を書きます」というプラカードを持って路上に立っているような人たちだ
    • 私の陰謀論を一つ言うなら、マイクロサービスというパターンをクラウドベンダーが後押しした結果こうなったのだと思う。- K8S のようなオーケストレーターなしでは実行もできないようにして、これでマネージドクラウドを売りやすくなる - より多くのネットワークトラフィックや CPU 使用で課金が増える - 大規模な状態共有が難しいので、マネージドデータベースやイベントキューが必要になる - ローカル実行が難しくなり、開発環境までクラウドコストにつながる - クラウド固有の方式に縛られて抜け出しにくくなる。昔、クラウドは IT コストを節約してくれると宣伝していたが、本当に笑ってしまう。2000年代の時点ですでにそれが幻想だと分かっていたし、結局は全部もっと高くなるだけだった
  • "複雑さ vs ティラノサウルスの一騎打ちで、grug は複雑さよりティラノサウルスを選ぶ。少なくともティラノサウルスは目に見えるからだ" という一文は、週に一度は思い出すほど印象的だ
    • 引用: "転びながらも Leyster はシャベルを手放していなかった。混乱の中でその事実を忘れていたのだ。そこで必死にシャベルを持ち上げ、子どものティラノサウルスの脚に振り下ろした……"。ティラノサウルスとの極限のサバイバル闘争を生々しく描いた場面だ。最終的には仲間の Tamara が勇敢にも槍でティラノサウルスの顔の真ん中を突いて危機を乗り越える瞬間が訪れる。戦闘と緊張感、そして静寂の場面が印象的だ
    • grug はきっと「見えない」ティラノサウルスと戦ったことがない。私は今も見えないティラノサウルスと1対1で戦っていて、本当に大変だ
  • この文章で感心する点は、著者が「もっと複雑なこと」をできるのに、経験的にその道を選ばないことだ。もちろん抽象化や複雑さが必要な時と場所はあるが、grug の哲学は、そうしたもの自体に本質的な価値はないと言っている。これは本当にもっともだと思う。AI も一貫していてデータに基づいたコードのほうが効果を発揮しやすいと感じる
    • 複雑さや抽象化を使うのは、それによってコードが以前より理解しやすくなるときだ。「理解するために特別講座が追加で必要にならないとき」という前提を忘れないようにしたい。(状況によるが)
    • "すべては可能な限り単純にすべきだ。しかし、単純すぎてはいけない"
  • これが 2022 年の記事だなんて信じがたい。もう10年前に読んで「古典」だと思っていたような感覚だ
  • このエッセイは、ソフトウェアを作ることについて私がいちばん好きな文章だ。文体も魅力的だし(人によっては拒否感があるかもしれないが)、本質はいつでも有効だ
  • "悲しいが事実だ: 'yes' を学び、失敗したら他の grug のせいにする方法を学ぶことが、最高のキャリア戦略" というコード片は現実そのものだ。私も最初は会社で単に技術チームのコミュニケーションの問題が原因だと誤解していたが、(grug のように)実際にそうなのだと時間が経つにつれて学んだ
  • これまで見た visitor pattern の説明の中で、この記事の内容が最高だ
    • 私は典型的な OO コードベースで働いていないので visitor pattern が何なのかちゃんと分かっていなかったのだが、"Crafting Interpreters" というインタプリタ/VM を作る本を勧めたい。その本では visitor pattern を実際にどう使うのかが出てくる。自分で読みながら複雑さの理由を理解しようと努力したが、結局 tagged union で置き換えていた。たぶん自分が OO に弱いだけかもしれないが、grug の記事の要点もこれと同じだ。わざわざ複雑さや間接性を引き受ける必要がないなら、もっと直感的な方法があるということだ
    • 私はネーミングに敏感なほうだが、visitor pattern という名前は曖昧すぎて不満だ。実際に Visitor という名前で作ったことはない。たとえば構文木(AST)の演習なら、Visitor ではなく AstWalker、AstItem::dispatch(AstWalker)、AstWalker::process(AstItem) のような具体的な命名のほうがずっと意味がある。visitor とは「訪れる」というだけで、あまりに抽象的で意味が薄い。状況ごとに違うのが正しいし、単にコメントで ‘visitor pattern’ と明記しておけば認識の問題はない。昔、2つのオブジェクトツリーを突き合わせてデータを比較・インポートする必要があったとき、AbstractImporter という名前を使ったことがある。より具体的で、プロセスや役割も明確だった。典型的な visitor pattern とは違う
    • 実際に調べてみたら "Bad" という評価もあった。笑
  • 関連記事を共有する。ほかの人の意見や追加の記事はある?<br/><i>The Grug Brained Developer (2022)</i> - https://news.ycombinator.com/item?id=38076886 - 2023年10月(コメント192件)<br/><i>The Grug Brained Developer</i> - https://news.ycombinator.com/item?id=31840331 - 2022年6月(コメント374件)