はじめに
コードレビューなどで「この部分をリファクタしよう」と指摘した時に、「それってYAGNIじゃないですか?」と返されて困った経験ってないでしょうか?
念のために説明しておくと、YAGNIというのは「You Ain't Gonna Need It」の略で、「ヤグニ」と呼ばれるプログラミングの実装原則です。
一般的には「必要のない機能は実装するな」あるいは「必要になってから機能を実装しよう」という意味の実装原則として認識されています。(たぶん)
ただこのYAGNI、なんでもかんでも適用しようとすると「あれ、ちょっとおかしいな」となることがあります。
特にコードの書き方に関係する場合に発生しがちです。
なぜなら「その実装修正(=抽象化)が現時点で必要なのか・必要でないのか」を証明するのは、意外と難しいからです。
ではYAGNIはどう取り扱うのが正しいのでしょうか?
本記事では言葉自体が持つニュアンスを意識しながら、検討してみたいと思います。
コンテンツ
1. YAGNI適用の難しさ
最初の例に戻ると、この時の構図は以下と同義です。
私が「(このコードは後で拡張しやすいように)リファクタしよう」と指摘したら、実装者が「(拡張が必要になった時に実装すればよいので)YAGNIだと思います」と主張した。
しかし冷静に考えると「そんなこと言い出したら単一責務の原則(※1)もリスコフの置換原則(※2)も、実装したその瞬間は必要ないんじゃね?」ということになってしまいます。 極端な話、そのコミットを最後に一生追加実装が入らないのであれば、どんなコードで実装されていても構わないからです。
つまり「YAGNI = 必要のない機能は実装しない」という解釈は、正確でないということができます。
翻訳として間違っているとまでは言わないにせよ、ニュアンスを伝えきれていない、というイメージです。
ではこのYAGNIの原則、いったいどう取り扱うのが正解なのでしょうか?
その疑問を解決するカギは<YAGNIというの言葉のニュアンス>にあると思っています。
※1 単一責務の原則
クラスやメソッドは複数の責務を保持してはいけない。
簡単な例を示すと、TableAndChairクラスはやめて、TableクラスとChairクラスに分けましょう、という感じ。
※2 リスコフの置換原則
派生クラスは(派生元である)基本クラスと置換可能でなければならない。
単純な例を示すと、チワワクラスは犬クラスとして動作しなければならない、という感じ。
2. YAGNIのニュアンス
そこにいる英語があまり得意でないあなた、正直に言いましょう。
You ain't gonna need it.
っていきなり言われて、意味わかりますか?
ちなみに、私は三田にあるぼちぼち有名な私立大学の英文科を出ていますが、この言葉を初めて見たときは「はて......」という感じでした。(←情けない)
まずは一歩ずつ確実にいきましょう。
この言葉を丁寧に言い直すと以下の通りとなります。
① You are not going to need it.
あなたはそれを必要としないでしょう
これならわかるのではないでしょうか? 中学校で習った未来形<be going to ~>です。
次にgonnaです。
英語のスラングでは going to を gonna と略すことがあるります。
ニュアンス含めて無理やり訳すなら以下のような感じになるでしょうか。
② You are not gonna need it.
それは必要ないと思う
最後に、問題の「ain't」です。
こちらは元々アメリカ南部(或いはイギリス農村地方)の方言だったようです。現在はスラングとして使われています。
このスラングはかなり汎用的で、am not, are not, is notなどの<be動詞 + not>的なものを全部「ain't」で言い換えることができます。(その他の用法もありますが、ここではこれ以上解説しません)
ニュアンスとしては「~だべ」とか「~じゃね?」くらいの感じだと思います。
よって、YAGNIの訳は以下の通りとなります。
③ You ain't gonna need it.
それ必要ねえべ
私にはこんなシーンが目に浮かびます。
シリコンバレーのあるオフィスで、PCモニターを前に二人のプログラマが話をしています。そのうちの一人<プログラマA>が、カクカクしかじかの理由でこれこれの機能を実装しようと思っている、と伝えます。すると<プログラマB>がこう言います。
Actually, you ain't gonna need it.
ぶっちゃけ、それ必要ねえべ
私のイメージする You ain't gonna need it. のニュアンスは、こんな感じです。
3. なぜ「モブコフの必要最低限実装の法則」ではないのか
もしこの実装原則の主張内容が「必要のない機能を実装するな」なのであれば、なぜわざわざ「YAGNI」などというスラングっぽい用語を用いたのでしょうか?
「必要のない機能を実装するな」が主眼なのであれば、「モブコフの必要最低限実装の法則」でもよいはずです。(←モブコフは架空の天才プログラマ)
あるいは「Don't Implement Unnecessary Feature」DIUFの法則(←適当に考えてみた原則名)でもよかったじゃん、という話です。
結論から言うと、YAGNIの主張は他の実装原則より優先順位が劣るからだと思います。
基本的には他の有名な実装原則が大前提として存在し、その適用範囲などで問題が複雑化した際に「YAGNI = それ必要ないんじゃね?」が登場するという順番なのです。(たぶん)
先ほどのイメージで説明してみます。
シリコンバレーのあるオフィスで、PCモニターを前に二人のプログラマが話をしています。そのうちの一人<プログラマA>は、自身が抱える設計方針の悩みを打ち明けました。
「コレコレの機能は将来拡張するかもしれないのでこのインターフェースを切りたいのだが、アレソレの仕様が変わったらこの実装は無駄になってしまうので、ユーティリティ・メソッドをこのように工夫して......」
彼が実装を初めてもう3日。
この機能がどの程度重要になるかは誰にもわかっておりません。
すると、それを聞いていた<プログラマB>がこう答えます。
「Actually, you ain't gonna need it.(ぶっちゃけ、それ必要ねえべ )」
彼は「そんな将来必要かどうかもわからない拡張性にこだわってないで、サッサと実装を進めようよ」ということが言いたかったのです。
4. 結論
以上が tumo.jp の考えるYAGNIの解釈でした。
まとめると「基本的にはYAGNIより重要な他の実装原則が先にあり、それら実装原則にこだわりすぎて仕事が進まない状況を避けるためYAGNIが存在する」という感じになります。
念のためですが
つまり、本記事の内容は全て tumo.jp の仮説です。
そのような前提の元、今後の参考にしていただければ幸いです。
最後までお読みいただきありがとうございました。
高評価・コメントなどいただけますと大変励みになりますので、どうぞよろしくお願いします。