「あとで必要になりそうですが、先に作っておきますか?」
開発していると、この誘惑は本当によく訪れます。設定オプションを先に用意し、多言語対応の構造も先に整え、管理画面から変更できるようにテーブルまで先に作ってしまいます。
今日取り上げるYAGNIは、まさにこの誘惑に正面から「いいえ」と答える原則です。KISS、DRYとともに、開発原則の三本柱と呼ばれています。
YAGNIは「You Aren’t Gonna Need It」の略です。「それ、どうせ必要ないよ」という意味です。
エクストリームプログラミング(XP)という開発手法から生まれた言葉で、ケント・ベックやロン・ジェフリーズなどXP陣営の人々が口癖のように使っていた表現が、原則として定着したものです。
核心となる主張は一つです。
機能は実際に必要になったときに実装する。必要になりそうだと予測したときではありません。
先に作ると何が問題なのか?
「先に作っておけば、あとで楽ですよね?」という反論がすぐ出てきそうです。問題は、その予測のほとんどが外れることです。
マーティン・ファウラーはこのテーマについてまとめた記事で、先に作った機能のコストを四つに分けています。
| コスト | 内容 |
|---|---|
| 実装コスト | 今すぐ使わない機能を作るために費やす時間 |
| 遅延コスト | その時間で作るべきだった本当の機能が遅れること |
| 維持コスト | 使わないコードにも、テスト・リファクタリング・バグ修正が継続的について回ること |
| 修正コスト | 実際に必要になった時点では要件が変わっていて、作り直さなければならないこと |
一番痛いのは最後です。「あとで」が本当に来たとき、その時点の要件は、予想していた形とほぼ必ず違います。結局、先に作ったコードを作り直すコストまで二重に払うことになります。
実務でYAGNIが破られる場面
言葉にすると皆うなずきますが、実際には次のような形で忍び込んできます。
1. パラメータを先に用意する
// 今はメール通知だけですが
func sendNotification(user: User, message: String, channel: String = "email",
retryCount: Int = 3, priority: String = "normal",
template: String? = nil) {
// channelこの "email"場合にだけ動作するコード
}
呼び出し元はすべてsendNotification(user: user, message: msg)だけです。残りのパラメータは「あとでSlack通知を追加するときに使うため」に作ったのですが、Slack通知の要件は結局入りませんでした。
2. プロトコルを先に用意する
実装が一つしかないのに、先にプロトコルを作るケースです。UserServiceを一つ作りながらUserServiceProtocolも同時に作るパターンですが、二つ目の実装が登場するまで、そのプロトコルはファイル数を増やすだけの飾りです。
3. 「設定に切り出しておくと便利ですよね」
ハードコードを恐れて、すべての値を設定ファイルや管理画面に切り出すケースです。実際にはその設定を変更することは年に一度もなく、設定が増えるほど「この値を変えるとどこに影響しますか?」という質問だけが増えていきます。
YAGNIではないもの
誤解を防ぐために、線引きしておきます。YAGNIは次のような意味ではありません。
まず、設計をするなという意味ではありません。コードを変更しやすくする努力(よい名前、小さな関数、テスト)は今すぐ価値があるため、YAGNIの対象ではありません。むしろコードを変更しやすくしておけば、「必要になったそのとき」に素早く作れます。
また、後戻りしにくい決定まで先送りしろという意味でもありません。データベースの選択やAPI公開仕様のように、一度決めると変更が難しいものは、先に検討するのが正しいでしょう。YAGNIが対象とするのは、「あとで簡単に追加できるのに先に作る機能」です。
私が使っている判断基準
私は「先に作っておこうか?」と思ったとき、二つのことを尋ねます。
この機能が必要だという根拠はロードマップにあるのか、それとも自分の想像の中にあるのか?
あとで追加すると、今よりはるかに高くつくのか?
根拠が想像で、あとから追加してもコストがほぼ同じなら、作りません。ほとんどの場合はこれに当てはまると感じます。
まとめ
YAGNIの原則から持ち帰ることは三つです。
- 機能は必要になったときに作りましょう。必要になりそうなときではありません。
- 先に作った機能は、実装・遅延・維持・修正のコストを四重に請求してきます。
- ただし、よい設計習慣と後戻りしにくい決定はYAGNIの対象ではありません。
KISS、DRYに続いてYAGNIまで並べてみると、三つの原則は結局一つの文にまとまります。今日必要なものを、シンプルに、一か所だけに作ること。
「いつか使うだろう」と作ったまま眠っている機能が一つでもあるなら、2年後に自分の手で削除することになるかもしれません。

