はなちるのマイノート

Unityをメインとした技術ブログ。自分らしくまったりやっていきたいと思いますー!

【C#】nullチェックを不要にできるNull Objectパターンを学ぶ

はじめに

今回はNullReferenceExceptionのスローを防ぐためのnullチェックを減らすことができるNull Object パターンについて紹介したいと思います。

f:id:hanaaaaaachiru:20210222171118p:plain
クラス図

よくあるnullチェック

class Client
{
    // UserObject のインスタンスを管理しているもの
    static IRespository _respository = new Repository();

    private static void Main(string[] args)
    {
        // userObjectを取得する
        var obj = _respository.GetUserObject();

        // nullチェックをしないといけない
        if (obj != null)
        {
            obj.Execute();
        }
    }
}

public class UserObject
{
    public void Execute()
    {
        Console.WriteLine("Execute.");
    }
}
f:id:hanaaaaaachiru:20210216205004p:plain
クラス図

Null Objectパターン適応後

Null Objectパターンは、何もしないNullObjectnullの代わりに用いることで解決します。

class Client
{
    // Abstractionのインスタンスを管理しているもの
    static IRespository _respository = new Repository();

    private static void Main(string[] args)
    {
        // IAbstractionを取得する
        var abstraction = _respository.GetAbstraction();

        // GetAbstractionメソッドの返り値はnullにならない(しないようにする)ためnullチェックが必要ない
        abstraction.Execute();
    }
}

public interface IAbstraction
{
    void Execute();
}

public class RealObject : IAbstraction
{
    public void Execute()
    {
        Console.WriteLine("Execut.");
    }
}

public class NullObject : IAbstraction
{
    public void Execute()
    {
        // 何も処理しない
    }
}
f:id:hanaaaaaachiru:20210222171118p:plain
クラス図

さいごに

クライアントを実装する人がNull Objectパターンを用いて実装されていることを知らされていなかった場合に結局意味がなくなってしまうのではないかとも思います。

C#は型が厳格なところが魅力ですし,おそらくインターフェイスは参照型であるという知識から自然とnullチェックを行ってしまうのではないでしょうか。

まあちゃんと情報共有やコメントを残しておけと言われればそうですが、シグネチャだけでは難がありそうです。

またクラスの数が増えてしまうデメリットもありますが、クライアントの簡素化・テストの容易化できるメリットもあるので,このパターンはそこらへんのトレードオフを考えてみると良いと思います。

ではまた。