Skip to content

14. 今いらないものは実装しない

作品の中で「こんなこともあろうかと」と有能な人が不測の事態を先読みして予め準備をしていた、なんてシーンはよくあります。しかし、開発においてそれはリスクになり得ます。こんな言葉があります。

それはきっと必要にならない

(You aren't gonna need it.)

Ron Jeffries

これは、原文の頭文字をとってYAGNI原則といいます。更にRon Jeffriesは次のように続けます。

常に、実際に必要になったときにだけ実装しなさい。単に必要になると予測しただけで実装しては決してならない。

(Always implement things when you actually need them, never when you just foresee that you need them.)

Ron Jeffries

確かに、ある程度先を見通しておくことは重要です。しかし、未来を気にするあまり今を疎かにしては本末転倒です。それに、仕様はどんどん変更される可能性があります。念の為用意しておいたものも、予想が外れればデッドコードになったりしてバグの原因となります。過度に拡張性を高めたりインターフェースを差し込みまくったりするのも単に手間が増えるだけです。

それは最適化についても同じです。確かにパフォーマンスを改善しようとすることはとても素晴らしいことです。しかし、その最適化は本当に必要なものでしょうか?

早すぎる最適化は、諸悪の根源である

(Premature optimization is the root of all evil.)

Donald E. Knuth

最適化に躍起になるあまり、コードが複雑になったり開発が滞ったりしていませんか?その最適化によって得られるパフォーマンスは本当に必要なものですか?結局ゲームが完成しなければ全てが無駄になります。まだ完成してもいないのに、まだパフォーマンスの問題が発生していないのに、ボトルネックが判明する前に勘でコードを複雑にしてまで最適化しようとするのは愚かです。

結局、ここで主張したいことは全てKISS原則で表されます。

シンプルにしておけ、この間抜け!

(Keep it simple, stupid.)

Kelly Johnson

コードはできるだけ現時点で必要な機能だけにしてシンプルに保ち、必要になったときに必要なものを実装しましょう。

csharp
// ❌ Bad: 「いつか使うかも」で作った未使用の拡張ポイント
public interface IBuffable { }
public interface IDebuffable { }
public interface IElemental { }
public abstract class StatusEffectBase<T> where T : IBuffable, IDebuffable { }

public class Player : MonoBehaviour, IBuffable, IDebuffable, IElemental
{
    // 今の仕様にはバフもデバフも属性もない…
    public int HitPoint { get; private set; }
    public void TakeDamage(int amount) { HitPoint -= amount; }
}

// ✅ Good: 今必要なものだけ
public class Player : MonoBehaviour
{
    public int HitPoint { get; private set; }
    public void TakeDamage(int amount) { HitPoint -= amount; }
}

Unity設計講習会 資料公開ページ