本文へスキップ
BecomeCoder

C#デザインパターンコース · 第3章 現代の設計パターン · レッスン25

Null Object パターン

ブラウザで完結

導入

if (logger != null) logger.Log(...) という null チェックがコード中に散らばると読みにくくなります。Null Object パターンは「何もしない実装」を用意しておき、null の代わりにそれを使うことで、呼び出し側の分岐を消します。

図解

flowchart LR
    C["呼び出し側"] -->|null チェック不要| I["ILogger"]
    I -.-> R["本物: 実際に記録"]
    I -.-> N["NullLogger: 何もしない"]
    style N fill:#eeeeee

サンプル

Run(new ConsoleLogger());   // [LOG] 開始 / [LOG] 終了
Run(NullLogger.Instance);   // 何も出ない(null チェックなしで安全)

void Run(ILogger logger)
{
    logger.Log("開始");
    logger.Log("終了");
}

interface ILogger { void Log(string message); }
class ConsoleLogger : ILogger { public void Log(string m) => Console.WriteLine($"[LOG] {m}"); }
class NullLogger : ILogger
{
    public static readonly NullLogger Instance = new();
    public void Log(string message) { /* 何もしない */ }
}
  • 「何もしない実装(Null Object)」を用意しておく
  • null の代わりにそれを渡せば、呼び出し側は if (x != null) を書かなくてよい
  • 存在しない担当者・空の設定などを安全に表現できる

やってみよう

Runnull を渡すとどうなるか(NullReferenceException)を確認し、NullLogger.Instance に替えると分岐なしで安全に動くことを比べましょう。

演習

interface INotifier { void Notify(string msg); }

// TODO: 何もしない NullNotifier を定義してください(Notify は空でよい)
___

void Process(INotifier n) { n.Notify("done"); Console.WriteLine("処理完了"); }
Process(new NullNotifier());   // 処理完了(通知は何も起きない)
  • 期待される出力: 処理完了
ヒント1を見る

class NullNotifier : INotifier { public void Notify(string msg) { } }

ヒント2を見る

Notify の中身を空にすれば「何もしない」実装になります

まとめ

  • Null Objectは「何もしない実装」で null チェックを消す
  • 呼び出し側の分岐が減り、NullReference事故を防ぐ
  • 「担当なし」「空の設定」を安全に表せる

次回: 条件をオブジェクト化する Specification パターンです。

実際に動かしてみよう

本文のサンプルや演習のコードは、コードブロック右上の「コピー」ボタンでコピーして、下のエディタに貼り付ければそのまま実行できます。

C# — ブラウザ内で実行

ブラウザ内でC#を動かす環境を読み込みます(初回のみ数秒)。
スクロールして表示された時点でも自動で読み込まれます。