- 大規模システムの実質的な設計への参加は、そのコードを直接扱うエンジニアにしかできず、抽象的な助言の大半は無意味である
- 一般的な設計助言(generic design) は、コードベースを知らないままドメインだけを理解して提示されることが多い
- 実務では、具体的な制約と一貫性の維持が設計原則よりはるかに重要であり、コードの現在の状態を理解することが核心である
- 新しいシステムの設計や会社全体の技術方針の決定では、一般的な設計原則が一定程度有効に機能する
- しかし、現場から切り離されたアーキテクト中心の設計構造は失敗しやすく、設計を提案した人が結果に責任を負うべきである
一般的なソフトウェア設計の限界
- 大規模システムの設計には、コードの具体的な細部に対する深い理解が不可欠
- 抽象的な助言は、実際の問題解決にはほとんど役に立たない
- 実務では、**一貫性(consistency)**が「良い設計」よりも重要である
- 実際のコードベースは複雑で予測不能な結果を生むため、安全な変更のために選べる実装方式は限られる
- 大規模な共有コードベースは、常に複数の設計が混ざり合った過渡的な状態にあり、理想的な目標より現在のコードの結合状態のほうが重要である
- ほとんどのシステムでは全面的な書き直し(rewrite)が不可能なため、内部の一貫性とエンジニアの細心さに依存せざるを得ない
具体的なソフトウェア設計の特徴
- 効果的な設計議論は、システムを日々扱う少数のエンジニア同士の会話の中で行われる
- 議論のテーマは一般原則ではなく、システムの詳細構造やデータフローなどの具体的な文脈が中心
- 例えば「DRYは良いか」ではなく、「この機能をAサブシステムに入れられるか、Bの情報がCコンテキストでアクセス可能か」といった細かな技術的議論が行われる
- 重要な貢献は、小さな誤解やコード変更の細部の影響を正すことから生まれる
一般的な設計助言が有用な場合
- 新しいプロジェクトを最初から設計するときは具体的な制約がないため、一般的な原則が有用
- 複数の実装案のどれを選ぶかが難しいとき、一般的な原則が**判断基準(tie-breaker)**として機能する
- 会社全体レベルの一貫性維持にも役立ち、これは公式なソフトウェアアーキテクトの役割の一つでもある
- クラウド vs オンプレミス、AWS vs Azureのような広範な技術選択でも一般原則は参考になるが、それでも具体的な制約は無視できない
アーキテクトと「ローカルミニマ」問題
- 多くの企業は、現場経験のないアーキテクト中心の抽象的な設計構造にはまりがちである
- この方式は見た目には効率的だが、実際には現場のエンジニアが実装できない設計を生み出す
- アーキテクトは自ら実装しないため、**成果への責任(skin in the game)**が不足している
- 設計が成功すれば手柄にし、失敗すれば実行チームの責任にできてしまう
- この構造は、実質的な価値より形式的な設計活動を強化する傾向がある
結論と提案
- 有用な設計議論はコード単位レベルの具体的な対話で行われ、設計者は必ずコードベースに精通していなければならない
- 一般的なアーキテクチャ原則は、新しいシステムの設計、既存システムの細部の意思決定の補助、会社レベルの技術方針設定に限定されるべきである
- プロジェクト設計を提案した人は、その成功と失敗に責任を負うべきであり、実際にコードを扱うエンジニアが設計の主体であるべきだ
- これによって、実際のシステムを理解しデプロイできる人が真の設計者として認められる
4件のコメント
> 実務では、具体的な制約や一貫性の維持が設計原則よりはるかに重要であり、コードの現在の状態を理解することが核心だということですね
普段からの自分の持論なので、胸が温かくなりますね
だから最近グルたちが、むしろ新人のほうがエージェントをずっとうまく使うと言っているのか。長く稼がせてくれたやり方だから、アンラーニングしないんだな。
アーキテクチャを完成させるプロセスを改善すれば、提起されている問題点は十分に解決できるのではないでしょうか?
Hacker Newsの意見
チーム会議で「DRYがよいかWETがよいか」といった話ではなく、「この機能をサブシステムAに入れられるだろうか? いや、そこではBの情報がなくて、それを公開するにはDを書き直さなければならなくて…」のような 複雑な依存関係の議論 が続く状況を描写している
見慣れた光景だという冗談めいた調子で複数の架空システム名を並べ、最後に YouTubeリンク を添えている
30年間開発をしてきたが、実際に 設計とアーキテクチャに一貫した努力を注ぐケース はほとんど見たことがない
ほとんどの「アーキテクト」は設計せず、シニア開発者が設計した後でフィードバックだけを受ける構図になっている
平均在籍期間が2年なら、システムの一部しか理解していないまま設計することになり、アーキテクトはただ承認するだけという場合が多い
「Generic Software Design」は実装の方向性を定めるのに有用だ。共通言語とフレーム を提供し、問題解決を容易にする
だが実際の実装は計画と異なることがある。Naurのプログラミング理論のように、システムの本当の知識は 開発者の頭の中 にある
「大規模コードベースでは一貫性がよい設計より重要だ」という言葉は、まさにその 一般化された助言 の落とし穴だ
一貫性ばかり強調すると、悪い習慣がそのまま維持されてしまう
一方には現実を知らない「アーキテクト」がおり、もう一方には細部の最適化にしか没頭しない Real Programmer がいる
両極端とも問題であり、意思決定者は細部と文脈の両方を理解していなければならない
関連する話として The Story of Mel に言及している
「設計した人がプロジェクトの成功と失敗に責任を負うべきだ」という言葉に同意する
これは 開発手法を選んだ人 にも適用されるべきだ。Scrum master はリードエンジニアほどの責任感を持っていない
私が関わった最高のアプリには、次の3つの特徴があった
この自由が、開発者満足度と製品品質の両方を高めていた
私の経験では、大規模コードベースでの 一貫性への執着はむしろ誤り だ
モジュールごとに要件が異なるため、テスト戦略や命名も変わるべきだ
理想的には、開発者は自分が作ったソフトウェアの 実際のユーザー でもあるべきだ
そうすれば不具合や使いにくさを自分で感じ取り、改善の動機が生まれる
保守に参加しない 別個のソフトウェアアーキテクト は非現実的だ
プロジェクトは絶えず変化するため、離れた場所から指示するだけの役割は役に立たない