ポエム:『YAGNIで思考停止しない』で思考停止しない

最近、設計界隈で『YAGNIで思考停止しない』という言葉をよく耳にする。
だが一方で、YAGNIについてあまり理解せずにこの言葉が使われているのではないかと思うことがある。
YAGNIを手抜きの手段だと捉え、そこで思考停止しているから、『YAGNIで思考停止しない』という言葉が出てくるのではないだろうか?
そんな嫌らしい邪推が頭から離れないので、文章にしてスッキリしようというのがこの記事の目的である。

復習:YAGNIとは?

YAGNIとは、「今必要ないものを作らない」ということだ。
YAGNIを理解するための重要なポイントは、「早さ」と「作り込みすぎない」という2点にある。

まず「早さ」について。
YAGNIで思考停止せずに3日間、うんうんと設計を考えて"素敵な"設計が浮かぶとしよう。
YAGNIを採用するということは、この素敵な設計を作るよりも、3日早く実装をしたほうが良いということだ。3日早くお客さんやビジネスサイドに動くものを提供したほうが良いということだ。3日早くリリースして、ユーザに価値を提供することもできる。もし作っているものがサブスクリプション型のサービスであれば、本来よりも3日分の売上を上げることもできる。つまり、YAGNIを採用するならYAGNIで思考停止すべきだ。思考停止せずにうんうんと考える時間がもったいない。
3日早めるということは、3日早くフィードバックが返ってくるということだ。この早さというものはビジネス上で非常に重要だ。3日前に知っていれば別の選択肢を取れたが、3日後だとその選択肢を取れなくなっていることは本当によくある。
また、フィードバックは知識だ。フィードバックを取り入れることにより、より良いものを作れるようになる。先延ばしにした設計が本当に必要になったときに、最初に設計したときよりも知識が多い状態で設計できる。逆に言うなら、最初にすべてを設計しようとすると、知識が欠乏した状態で設計することになる。

次に「作り込みすぎない」ことについて。
エンジニアは得てして作り込みをしすぎてしまう傾向にある。より抽象的に、より汎用的により応用の効くように作ってしまう傾向にある。それ自体は良いことだ。問題なのは、汎用性が不要なものですら汎用的に作ってしまうことにある。
「現状はS3をストレージとして使っているが、他のストレージに置き換えられるようにインターフェースを切っておこう」これはよくある話だ。だがよく考えてほしい。S3から別のストレージに置き換えることはあるんだろうか?その別のストレージが登場するまで、このコードは読みやすいんだろうか?この設計判断を知らない人がコードを読んだときに、理解しやすいだろうか?
特にバグ調査において、無駄に抽象的なコードほど厄介なものはない。スタックトレースとコードからコンテキストを理解するのに時間がかかるようになる。エラーが発生した行で呼び出されている Storage というインターフェースにどの実装が入っているのか調べる必要がある。だが、 S3Storage という実装から直接呼び出されているのであれば、そんな無駄な労力はかけなくて済む。将来の汎用性のために今現在にコストをかけるのは、非常に苦痛に感じるものである。

勘違いされていそうだが、手抜きの設計はYAGNIではない。YAGNIでは必要になったときに設計をするが、その設計を妥協していいわけではない。同様に「あとでリファクタリングする」もYAGNIの考えから離れている。リファクタリングが必要なのであれば、今するべきだ。YAGNIは品質に使われる言葉ではない。

YAGNIを適用するとき、しないとき

YAGNIはすべての開発に適用できるわけではない。
もしあなたがアジャイル開発をしているのであれば、YAGNIを適用できる。むしろ適用すべきだし、おそらくすでにYAGNIで物事がまわっているのではないだろうか。

もしあなたがアジャイルな開発ではなくアジャイル「で」開発している場合や、ウォーターフォールなどの規範的プロセスで開発している場合、YAGNIを適用するべきではない。というよりもYAGNIを実践できない環境にある。
繰り返しになるが、YAGNIとは「今必要ないものを作らない」ということだ。逆に言うなら「必要になったときには作らないといけない」ということだ。ものごとをフェーズで区切るようなプロセスを採用している場合、必要になったタイミングで作ることができないか、コストが多くかかってしまう。もしこのような環境で他のメンバーがYAGNIを提案してきたときには「YAGNIで思考停止しない」ではなく「うちはYAGNIを使えない環境なんですよ」と言うべきだろう。

YAGNIを適用するときに注意するポイント

アジャイルな開発をしている場合、毎日実装をし、毎日デプロイしているだろう。つまり「必要になったら」のタイミングが毎日来る。よって当然、毎日設計しなければいけない。少しでも最適な設計から外れてしまうとYAGNIによる恩恵は下がってしまうので、気を緩めないことが大事だ。少しでも設計をしやすいようにXPのプラクティスである「コードの縮小」は実践したほうがいいだろう。

YAGNIを適用する際に一番難しいのは見積もりだと思う。
今までの見積もりとかなり見積もり方が変わるだろう。なぜなら、簡単な機能追加であっても、最適な設計にさせるまでにコストがかかることがあるからだ。

  1. 初めて機能を実装するときは、価値を体現する必要があるのでまま時間がかかる
  2. 似た機能を実装するときは、抽象化をする必要があるので、そこそこ時間がかかる
  3. さらに似た機能を実装するときは、すでに抽象化されているので時間はかからない

最初は難しいかもしれないが、感覚を掴めばわりといける。

YAGNIを適用しないときに注意するポイント

YAGNIを適用せず、つまり「もし〇〇したいと思ったときに」という設計をする場合、以下のポイントに注意する必要がある。

  1. 「〇〇したいと思ったとき」が来なかった場合にその設計はわかりやすいか
  2. 設計をしてからその「〇〇したいと思ったとき」が来るまでの間、その設計はわかりやすいか
  3. 「〇〇したいと思ったとき」が来たときに、システムの前提が今と変わらないか

まとめ

  • YAGNIは「今必要ないものを作らない」ということ
  • YAGNIでは早さと作り込みの防止が重要である
  • アジャイルな開発を行っていない場合、YAGNIを使ってはいけない

YAGNIアジャイルラクティスを発祥とする考え方だ。よってYAGNIを理解するためにはアジャイルな考え方を理解する必要がある。特にXPの技術的プラクティスについては前提知識として踏まえておいたほうがいいだろう。