Yagni

2015年5月26日

Yagniは、「You Aren't Gonna Need It(必要ないだろう)」の頭字語です。エクストリームプログラミングのモットーであり、アジャイルソフトウェア開発チームで一般的に使用されています。これは、ソフトウェアが将来必要になると想定している機能を、今は構築すべきではないという主張です。「必要ないだろう」からです。

Yagniは、XPの実践であるシンプルデザイン(『The White Book』初版からのもの。第2版では関連する「増分設計」の概念を参照)を示す方法です。[1] XPの多くの要素と同様に、90年代後半に広く受け入れられていたソフトウェアエンジニアリングの原則とは対照的です。当時、ソフトウェア開発の綿密な事前計画が大きく推進されていました。

ミナスティリスで海運業の保険を販売するスタートアップ企業で働いているとしましょう。彼らのソフトウェアシステムは、価格設定用と販売用の2つの主要なコンポーネントに分割されています。依存関係上、関連する価格設定ソフトウェアが完成するまで、販売ソフトウェアを効果的に構築することはできません。

現在、チームは嵐によるリスクに対応するために価格設定コンポーネントの更新に取り組んでいます。6ヶ月後には、海賊行為のリスクの価格設定にも対応する必要があることを知っています。現在価格設定エンジンに取り組んでいるため、価格設定サービスを販売ソフトウェアに取り掛かる前に完成させるため、海賊行為の価格設定に関する推定機能[2]を今構築することを検討しています。

Yagniはこれに反対し、6ヶ月間海賊行為の価格設定は必要ないため、必要になるまで構築すべきではないと主張します。したがって、このソフトウェアの構築に2ヶ月かかると予想される場合、スケジュールリスクと販売コンポーネントの更新のためのバッファ時間を考慮せずに、さらに4ヶ月間は開始すべきではありません。

Yagniの最初の議論は、現在この推定機能が必要であると考えているとしても、おそらく間違っているということです。結局のところ、アジャイル手法の文脈は、変化する要件を歓迎することを受け入れているということです。計画駆動型の要件の専門家は、これは要件分析を十分に行わなかったためであり、より多くの時間と労力を費やすべきだったと反論するかもしれません。私は、事前にニーズを把握することがいかに困難でコストがかかるかを指摘することで反論します。しかし、たとえ把握できたとしても、ゴンドールの海軍が海賊を一掃し、ビジネスモデル全体を損なう可能性があります。

この場合、推定機能には明らかにコストがあります。つまり、**構築コスト**です。この現在役に立たない機能の分析、プログラミング、テストに費やされたすべての努力です。

しかし、ニーズの理解が完全に正しく、ゴンドールの海軍が海賊を一掃しなかったとしましょう。この好ましい場合でも、推定機能の構築には2つの深刻なコストが発生します。最初の費用は、**価値の遅延コスト**です。海賊行為の価格設定ソフトウェアに努力を費やしたことで、他の機能を構築しませんでした。代わりに、気象リスクに関する販売ソフトウェアの構築にエネルギーを注いでいれば、完全な嵐リスク機能を運用に投入し、2ヶ月早く収益を上げることができました。推定機能によるこの**遅延コスト**は、嵐保険による2ヶ月の収益に相当します。

人々が推定機能を構築する一般的な理由は、後で構築するよりも今構築する方が安価だと考えているからです。しかし、そのコスト比較は少なくとも遅延コストに対して行われる必要があり、できれば不要な機能を構築している確率(少なくとも⅔)を考慮に入れる必要があります。[3]

多くの場合、人々は今構築することと後で構築することの比較コストを検討しません。この状況で開発者を指導するときに私が使用するアプローチの1つは、後で機能を導入するために必要な**リファクタリングを想像する**ように依頼することです。多くの場合、その思考実験は、後で追加する方が大幅に高価にならないことを彼らを納得させるのに十分です。そのような想像のもう1つの結果は、現在簡単に実行でき、複雑さを最小限に抑えながら、後のコストを大幅に削減するものを追加することです。インラインリテラルではなくエラーメッセージにルックアップテーブルを使用することは、シンプルでありながら後の翻訳を容易にする例です。

使用されない拡張ポイントは、無駄な努力であるだけでなく、邪魔になる可能性もあります。

-- Jeremy Miller

遅延コストは、成功した推定機能が課す1つのコストですが、もう1つは**維持コスト**です。推定機能のコードはソフトウェアに複雑さを追加し、この複雑さはソフトウェアの変更とデバッグを困難にし、他の機能のコストを増加させます。海賊行為の価格設定機能をソフトウェアに追加することによる余分な複雑さは、嵐保険販売コンポーネントの構築にかかる時間を数週間追加する可能性があります。その2週間は2つの方法で影響します。機能を構築するための追加コストと、運用に投入するのに時間がかかったことによる追加の遅延コストです。海賊保険ソフトウェアが役立つようになるまでの間、構築されたすべての機能に対して維持コストが発生します。海賊行為の価格設定ソフトウェアが決して必要ない場合、海賊行為の価格設定機能を削除するまで(削除する場合)、構築されたすべての機能に対して維持コストが発生し、削除コストも発生します。

これまで、推定機能を成功と失敗の2つのカテゴリに分類してきました。当然のことながら、実際にはスペクトルがあり、そのスペクトルの1つの点が注目に値します。それは、**適切な機能を間違った方法で構築する**ことです。開発チームは、ユーザーとコードベースの両方について常に学習しています。彼らは使用しているツールについて学び、これらのツールは定期的にアップグレードされます。彼らはまた、コードがどのように連携するかについても学びます。これらすべてを意味することは、6ヶ月前にコーディングされた機能が、現在認識されているべき方法で行われていなかったことに気づくことがよくあります。その場合、技術的負債が蓄積され、その機能の**修復コスト**またはその困難を回避するための継続的なコストを考慮する必要があります。

したがって、推定機能の3つのクラスと、Yagniを無視した場合に発生する4種類のコストが得られます。

私の保険の例は、比較的ユーザーに見える機能について説明していますが、同じ議論は将来の柔軟性をサポートするための抽象化にも適用されます。嵐リスク計算機を構築する際には、後で海賊行為やその他のリスクに対応するために、現在抽象化とパラメーター化を行うことを検討する場合があります。Yagniは、他の価格設定機能が必要ない場合、または実際に必要になった場合に、現在の抽象化のアイデアが学習した内容と一致しないため、これを行うべきではないと述べています。これは、すべての抽象化を放棄することを意味するわけではありませんが、現在の要件のコードの理解を困難にする抽象化はすべて有罪と推定されることを意味します。

Yagniは、より大きな機能では最も目立ちますが、小さなことではより頻繁に見られます。最近、コードの一部を強調表示できるコードを書きました。そのため、強調表示されたコードを正規表現を使用して指定できるようにしました。これに関する問題の1つは、正規表現全体が強調表示されるため、強調表示したいものよりも大きなセクションに一致する必要がある場合に対処できないことです。グループ内の正規表現を使用して、グループが存在する場合はコードがグループのみを強調表示するようにすることで解決できると思います。しかし、まだ強調表示するよりも多くのものに一致する正規表現を使用する必要がないため、強調表示コードをこのケースを処理するように拡張していません。そして、実際に必要になるまで拡張しません。同様の理由で、実際に使用する準備ができるまで、フィールドやメソッドを追加しません。

このような小さなYagniの決定は、プロジェクト計画のレーダーの下を飛びます。開発者として、すぐに必要になるであろうと確信している抽象化を追加するのに1時間費やすことは簡単です。しかし、上記のすべての議論は依然として当てはまり、多くの小さなYagniの決定は、コードベースの複雑さを大幅に削減し、より緊急に必要な機能の配信を高速化します。

Yagniが重要な理由を理解したので、Yagniに関する一般的な混乱を掘り下げることができます。**Yagniは、推定機能をサポートするためにソフトウェアに組み込まれた機能にのみ適用され、ソフトウェアを変更しやすくするための努力には適用されません。**Yagniは、コードが簡単に変更できる場合にのみ実行可能な戦略であるため、リファクタリングに努力を費やすことはYagniの違反ではありません。リファクタリングによりコードはより柔軟になるからです。自己テストコード継続的デリバリーなどの実践にも同様の理由が適用されます。これらは進化型設計のための有効な実践であり、これらがないとYagniは有益な実践から呪いへと変わります。しかし、柔軟なコードベースがある場合は、Yagniはその柔軟性を強化します。Yagniは、進化型設計によって有効になり、進化型設計を有効にするという興味深い特性を持っています。

Yagniは、コードベースの健全性を無視する正当化ではありません。Yagniは柔軟なコードを必要とし(そして可能にします)。

また、Yagniは、後で利用しない余分な複雑さを現在導入する場合にのみ適用されると主張します。ソフトウェアの複雑性を実際に増加させない将来のニーズのために何かを行う場合、Yagniを呼び出す理由はありません。

これらすべてを述べた上で、Yagniを適用すると問題が発生し、以前の変更よりも高価な変更に直面することがあります。ここで難しいのは、これらのケースは事前に見つけるのが難しく、Yagniが努力を節約したケースよりも覚えやすいことです。[4]私の感覚では、Yagniの失敗は比較的まれであり、そのコストはYagniが成功した場合に容易に上回られます。

参考文献

私のエッセイ「Is Design Dead」は、アジャイルプロジェクトにおける設計とアーキテクチャの役割、そしてYagniが有効な実践として果たす役割について詳しく説明しています。

この原則は、Ward's Wikiで最初に議論され、詳細に説明されました。

注記

1: このフレーズの起源は、C3プロジェクトにおけるKent BeckとChet Hendricksonの初期の会話です。Chetは、システムがすぐに必要とする一連の機能を持ってKentにやってきましたが、Kentはそれぞれに「必要ないだろう」と答えました。Chetは学習が早く、すぐにYagniを適用する機会を見つける能力で有名になりました。「yagni」は頭字語として始まりましたが、今では私たちの語彙に普通の単語として入り込んでいると感じているため、大文字は使用しません。

2: この投稿では、「推定機能」という用語を使用して、まだ使用可能になっていない機能をサポートするコードを指します。

3: Kohaviらは、Microsoftの製品で構築および展開された機能の価値を分析し、綿密な事前分析を行った場合でも、そのうち3分の1だけが設計された指標を改善したことを発見しました。⅔という数値はこれに基づいています。

4: これは、可用性バイアスの結果です。

謝辞

レイチェル・レイコックがこの記事について私と議論し、最終的な構成に重要な役割を果たしてくれました。チェット・ヘンドリクソンとスティーブン・ロウは、小規模なYAGNI(必要となるまで実装しない)の決定について検討するよう思い出させてくれました。レベッカ・パーソンズ、アルバロ・カヴァルカンティ、マーク・テイラー、アマン・キング、ルーアン・ウィルゼナッハ、ピーター・ギラード・モス、キフ・モリス、イアン・カートライト、ジェームズ・ルイス、コルネリス・シーツマ、ブライアン・メイソンは、社内メーリングリストでこの記事の草稿について洞察に富んだ議論に参加してくれました。