YAGNI (You ain't gonna need it) [1] は便利な言葉だ。似たような言葉にKISS [2] なるものがあるが、シンプルにしろ!と言われるより、 そんなものいらん!と言われる方が私にはしっくりくる。他人のコードをレビューするときも、「YAGNIの考え方からして、この部分は不要なんじゃない?」という方が「お前のパッチは無駄に複雑だ!」というよりは説得力がある、と思う。
YAGNI が有用な考え方なのは、無用な複雑化を避けられるからだ。premature optimization (早計な最適化)は諸悪の根源、という考え方があるが、私からすると、premature complication (早計な複雑化)はさらにたちが悪い。ソフトウェアは規模が大きくなるにつれ、多かれ少なかれ複雑化は避けられないものだが、複雑化の進行は遅いに越したことはない。
とりわけ、抽象化のレイヤーを入れるときは、本当にそれが必要なのか、YAGNIじゃないのか、と考えるといい。zipファイルを扱うコードを書くとしよう。このとき、ありがちなのが「zipファイル以外にも将来サポートするかもしれないから、ここは ArchiveReader というインタフェースを作って、ZipReader はそのひとつの実装にしよう」みたいなアイディアだ。一見、きれいな設計にみえるが、zipファイルしかサポートしないのなら(たぶんそうなるだろう)、無用なレイヤーがひとつ増えて、コードの見通しが悪くなるだけだ。
このように YAGNI は強力な考え方なのだが、外向けのAPIをデザインするときには、そんなのいらない!とばかりは言っていられない。内部的なコードだったら YAGNI式に作っておいて、後から変更できるが、外向けのAPIでは一度提供したものを、ほいほいと変えるわけにはいかないからだ。YAGNIスタイルが最も効果を発揮するのは、呼び出し側のコードをまとめて変更できる場合だ。
この「呼び出し側のコードをまとめて変更できる」ことは非常に強力な武器だ。これについてはまた別の機会に書いてみたいと思う。
[1] http://ja.wikipedia.org/wiki/YAGNI
[2] http://ja.wikipedia.org/wiki/KISS%E3%81%AE%E5%8E%9F%E5%89%87