ディスカッション (10件)
よく耳にする「YAGNI(You Ain't Gonna Need It:それは必要にならない)」という原則。多くのエンジニアは「今すぐ不要なコードは書くな」という意味で捉えていますが、実はこの言葉が指し示す本質的なコストは別のところにあります。それは、本当に必要な機能まで後回しにしてしまうリスクや、将来的な拡張性を排除しすぎることで発生する「技術的負債」の代償です。YAGNIは単なる手抜きのための免罪符ではなく、エンジニアが賢く設計判断を下すための武器であるべきです。今一度、この原則の真の意味を考えてみませんか?
リファクタリングのコストも下がってるよね。
AIのおかげで、リファクタリング前にテストで挙動を補強するコストが下がったし。
ゼロダウンタイム移行を実装するコストもAIのおかげで下がった。
Rustがこれだけ盛り上がった大きな理由の一つは、AIの登場前でもアプリ内のリファクタリングのコストが低かったから。今ではさらにその恩恵が大きくなってる。
安全にリファクタリングできないことによる機会損失は、大幅に増大してるんだよね。
今、自分が何よりも最適化しているのはここ。コードやプロダクトの重要な部分を、素早く安全に変更できる能力だ。
稼働中のソフトウェアを資産と捉えるのは正しいアプローチだ。
でも、実際に動かしたりやり直したりするコストは劇的に下がった。
下がっていないのは、予測可能な結果に対する「信頼の連鎖」を壊すコストだね。特定のバージョンの稼働中ソフトウェアには信頼が蓄積されている。もしゼロから書き直せば、リリースした時点でその資産はリセットされてしまう。
これは「予測が難しい」という議論に対する反論にはなっていない。まるで優れたアーキテクトならそれを回避できるかのように言っているが。
これには同意できないな。その議論は「予測が難しいからこそ」成り立つものだから。
Kent Beckは、書かれていないコードを、ある価格で何かを購入する金融オプションに例えているね。
でも、それは単なる例えだし、突き詰めすぎるとダメかも。まだコードを一行も書いていないなら、無限の選択肢を持っていると言えるのか? 時間をかけていないとはいえ、それは少し違う気がする。何かにコミットするのを避けるために、計画段階にとどまってコードを書くことを先延ばしにする口実に使われてしまいそうだし。
なぜその例えが成り立つのか?
たぶん、コストとは「コードを読むこと」にあるんじゃないかな。書かれていないコードは読む必要がない。それにAIコーディングエージェントを使っていれば、関係のない詳細でコンテキストを汚すこともないしね。
それに、書かれていないコードはテストも不要だ。まだ書いていないテストを実行する時間もかからない。
これが、プロジェクトを可能な限り小さく保とうとする正当な理由になる。機能の実装を後回しにすることで、コードベースの肥大化をできるだけ遅らせられるんだ。
これはつまり、他人のコードを動かすことで多くのコストを回避できるということだ。標準APIを使えば、実装の詳細を理解したりテストを実行したりする必要はない。もちろん、依存関係を追加するリスクはあるけどね。
自分の基本的な考え方は、コードを削除するコストを極限まで低くすべきということ。それにはアプリケーション全体も含まれる。データさえ手元にあって再利用しやすければ、プログラム自体はできる限り削除可能な状態にしておくべきだ。
(一般的に、AI時代におけるベストプラクティスをもっと強調すべきだと思うんだけど…)
Kentがここで完全に無視しているのは、必要な機能が何なのかを「より早く」見つけ出すことには大きな価値があるという点だ。推測で構造を構築することは、要件を確定させるための強制力として働く。少なくとも失敗のパターンを露呈させ始めることができるからね。待つよりコストはかかるかもしれないし、ほとんどの要件に対してやるべきではないけど、時にはそれが最善の選択肢になることもある。
作るべきでないものを作ってしまうコストは今やずっと低くなった。つまり、YAGNIを取り巻く計算式は変わったということだ。でも、それはあくまで計算の問題であって、各チームが自分たちにとってどう変わったのかを見極める必要がある。
個人的には、すべては課題に対する解決策を探求し実装することに行き着くと思う。間違った問題を解決することには常にコストが伴うんだ。あるいは、必要ですらないもののために悪い解決策を実装することもね。
時としてソフトウェア開発は、戦略や探求すべき課題について考えるのではなく、単なる試行錯誤のアプローチに成り下がってしまうことがある。
特定の方向性に必要以上に踏み込んで課題を探求することが、長期的に役立つケースはある。でも、目的もなく解決策を実装するのは決して良い考えじゃない。
Kent Beckが本当に言いたいのはこのことで、「将来必要になるかもしれないから」という理由だけで実装するようなやり方を批判しているんだと思う。
https://en.wikipedia.org/wiki/You_aren't_gonna_need_it 念のため、知らない人がいるかもしれないから貼っておくね。
ある時点で自分の考えがガラッと変わったんだ。
自分は、具体的な実装に対するYAGNIを適用して、可能な限り抽象化されたバージョンを書くようにしている。
例えばUserStoreを書くか?それが一番シンプルだろって思うかもしれないけど、違うんだ。その「Userの特定の構成」が必要になるとは限らないから。だから、ただ「保存可能なものすべて」のためのストアを作ることにする。
慣れていない人から見ると、過剰設計でジェネリクスのスープみたいに見えるかもしれない。でも逆説的に、そうすることで特定の具象実装へのコミットを最小限に抑えられるんだ。