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
コードはできるだけ現時点で必要な機能だけにしてシンプルに保ち、必要になったときに必要なものを実装しましょう。
// ❌ 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; }
}