
2025/12/29 16:54
自分が関わらないソフトウェアは、設計することはできません。
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
要約
大規模ソフトウェアプロジェクトでは、実際にコードを書き維持しているエンジニアから効果的な設計が生まれるべきです。彼らは細部を熟知しており、現実的な意思決定が可能です。汎用的で高レベルの指針は具体的なコードベースに合わないことが多く、既存パターンとの一貫性とシステムの実際的制約が選択を導くべきです。Hacker News の議論では、意見の相違は主に優先順位の差から生じると指摘されました。一部は確立された原則への厳格な遵守を主張し、他方は現在のコード状態への実用的適応を強調します。
重要ポイント
- エンジニアのみが具体的な詳細について有意義に議論できる。彼らこそがコードベースを深く知っている。
- 汎用的「問題に合わせて設計する」アドバイスは、主に全く新しいプロジェクトで役立つ。数個の具体的オプションの決定や会社全体のアーキテクチャ(例:クラウド vs. データセンター)の意思決定に有用だが、日常業務では既存システムへの知識不足から無効になることが多い。
- 大規模コードベースでは理想化された原則よりも一貫性が重要。実世界の制約は安全な実装選択肢を数に限定し、これらの制約は予測困難な結果を招くことがある。
- 優れた設計はサブシステム間の相互作用に深く精通した小規模グループで行われる。抽象的な「大局観」ミーティングではなく、実際のエンジニアリングチーム内で行われるべき。
- 建築家は新しいイニシアティブに対する長期的経路を設定し、トレードオフ解決を支援し、広範な技術選択を導くことに焦点を当てる。すべてのプロジェクトを完全に担当するよりも重要。
- デザイナーは自身の推奨が実際にどのように実行されるかについて責任を負う。成果と功績は実装を担うエンジニアと連動すべき。
コードを理解している者に意思決定権限を委ねることで、組織は設計決定を実装現実とより良く整合させ、達成不可能なアーキテクチャ理想に時間を浪費することを回避できる。
本文
大型ソフトウェアシステムに携わるエンジニアだけが、設計プロセスに実質的に参加できる。
それは、具体的なシステムの詳細を深く理解しないと良い設計は出来ないからだ。言い換えれば、一般化されたソフトウェア設計の助言は、多くの場合実際の設計課題には役に立たない。
一般化されたソフトウェア設計とは
「問題に合わせて設計する」こと、すなわちドメインをある程度把握しているが既存コードベースについてほとんど知らない状態で行う助言だ。残念ながら、これがソフトウェア書籍やブログ記事で最も多く見られるタイプの助言である。
エンジニアは「ショップを話す」ことを好きだから一般化設計の助言を出しやすい。しかし、日々直面する具体的な課題に対しては注意深く適用すべきだ。
実務では、具体的要因が一般的要因よりも圧倒的に重要になる。
現在のコードがどう見えているかを正確に把握することは、一般設計パターンや原則を理解しているよりずっと大切である。例えば:
- 大規模コードベースでは「良い設計」よりも一貫性が重要になる(私は Mistakes engineers make in large established codebases で詳細に議論した)。
- 実際のコードは複雑で予測不可能な副作用を伴う。安全に変更を加えるには、実装選択肢が極限まで絞られる。
- 大規模共有コードベースは常に複数設計の中間状態にある。個々の変更後にコードベースがどう結合するかが、理想的な「北極星」よりもずっと重要である。
もしシステム全体を自由に書き直せるなら、一般化設計は非常に実用的だ。そういうプロジェクトもあるが、大多数のソフトウェア開発は安全に書き換えられない既存システム上で行われる。こうしたシステムでは「設計」よりも内部一貫性とエンジニアの慎重さが求められる。
具体的なソフトウェア設計
それでは、良い設計とは何か?私の経験上、有用な設計はシステムを深く理解している少数のエンジニア間で行われる会話に現れる。
外部者から見るとこれらの議論は退屈に思えるが、実際には「DRY vs WET」などの抽象的原則ではなく、システム固有の詳細を巡っている。
例:
- 「この新機能をサブシステムAに入れられるか?」 → 「いいえ、情報Bが必要だがコンテキストCでそのサブシステムには無い。Dをリライトしないと露出できない。しかしEをこことそこに分割すれば…」
- 哲学的な設計原則はほとんど議論の中心にならず、むしろ「BがCで利用不可と思っていたが、最近Cをリファクタリングしたので必要ならBをスレッドできる」といった小さな誤解を指摘することが重要になる。
一般化設計が有効な場面
実務上の設計問題にはあまり役立たないものの、全く無意味というわけではない。
新規プロジェクトを立ち上げる際には具体的要因が存在しないため、一般化設計で完全に導かれることが可能だ。
また、既存システム内で複数候補があるときの決定打ちとしても有用だ。
個々のエンジニアは具体的実装を担うため、最終的な選択は彼らに委ねられるが、一般原則を提示しておくことで全社的な一貫性を保つことができる。
さらに、企業規模での技術方針決定(オンプレミスかクラウドか、K8sは使うか、AWS vs Azure)は、具体的サービスレベルではなく大枠を考える場面において一般設計が指標となる。
ただし、この段階でも具体的詳細は重要である(例:クラウドなら実装できない専用ハードウェア、オンプレミスならエッジデプロイが難しいなど)。これらを無視すると後々大きな問題になる。
アーキテクトとローカルミニマ
一般化設計を推奨する理由は多いが、実際にそれを行う企業は「上位レベルの決定を任せる」という魅力的に聞こえるため、止められない。
高給のエンジニアを抽象的な意思決定だけに従事させると、現場で実装できず、設計が形にならないケースが多い。
結果として「トップエンジニアは一般化設計のみ担当」というモデルは、
- 実際の実装者からは無視されやすい
- アーキテクトは成果をクレームできる(成功なら自分の設計)
- 失敗した場合は「フォロワーが従わなかった」と転嫁しやすい
という二重構造に陥りやすい。
要約
大規模既存コードベースで有効な設計議論は、実際にはファイル単位・行単位の具体的話題が中心だ。
そのため、実用的な設計を行うにはコードベースに精通していること(多くの場合アクティブコントリビュータであること)が不可欠。
純粋に一般化された設計は以下のケースでのみ役立つ:
- 新規システム構築 – 全体的な設計方針を提示
- 既存システムの決定打ち – 複数候補があるときに原則で選択
- 企業全体の技術戦略 – クラウド vs オンプレミス、K8s導入など
「大枠を設計し続けるアーキテクト」役割は失敗しやすい。
プロジェクト設計に関わった者がその成功・失敗の責任を取るべきであり、実際にコードベースを扱う人こそが難しい設計作業を行い、その成果を評価されるべきだ。
追記
Hacker News のコメントで「一貫性について同意しない」声があった。
Mistakes engineers make in large established codebases の受容は好評だったと覚えている。
「一般化設計は矛盾している」という指摘には、上記の「いつ有効か」の章で説明したように対処した。
もしこの記事を気に入っていただけたら、新しい投稿のメール更新や Hacker News への共有をご検討ください。
関連トピックとして Pure and impure software engineering をご紹介します。