Null Objectパターン

      2018/06/15

初期状態など何も処理を行いたくない場合、その状態を管理しているオブジェクトにNull(null, NULL)を設定・判定を行う、昔からのC言語に慣れている人が良く使う手法があります。
この場合、NullPointerException(所謂ヌルポ(null pointer reference))を見たことがある人も少なくはないでしょう。

下記はNullを設定するパターン(Nullableパターン)の簡単なソースコードです。(C#ですが、どの言語でも考え方は同じです)

Nullableパターン

class SampleState
{
    public string GetName() {
        return "SampleState";
    }
}
private SampleState _state = null;

private void PutStateString() {
    if (_state != null) {
        string name = _state.GetName();
        formTextBox.Text = name;
    }
}

これだけなら大した事はありませんが、実際に_stateを使用する箇所が増えると、都度Nullチェックを書くことになります。
プロジェクトが大きくなると、Nullチェックを忘れる事も。

個人的にはC#やJavaなど、クラスの概念がある言語でNullPointerExceptionを発生させるのは設計ミスだと思っています。
今まで経験したプロジェクトでは画面の表示部分で発生させるという何ともお粗末なものもありました。

以下はNullを使用しないパターン(Not-nullableパターン)のソースコードです。

Not-nullableパターン

abstract class StateBase
{
    public virtual bool IsNull() {
        return false;
    }

    public virtual string GetName() {
        return "StateBase";
    }
}
class SampleState : StateBase
{
    public override string GetName() {
        return "SampleState";
    }
}
class NullState : StateBase
{
    public override bool IsNull() {
        return true;
    }

    public override string GetName() {
        return String.Empty;
    }
}
private StateBase _state = new NullState();

private void PutStateString() {
    string name = _state.GetName();
    formTextBox.Text = name;
}

_stateNullチェックが無くなり、スッキリしたのが分かると思います。
IsNull()メソッドは初期化状態かどうかを知る必要がある場合のみ使用します。

StateBaseクラスを抽象クラスでなく通常クラスとし、それをNullStateクラスの変わりに使用することも可能です。
その際は、各継承クラス毎にIsNull()のオーバーライドなどが必要になります。

このようにNULLを使用しないパターンをNull Objectパターンと言います。
多態性についても知っておく必要がありますが、設計段階でNullPointerExceptionが潰せるのは、後の試験工数から見ても非常に有意義な設計パターンです。

 - 設計