夜 - Null Objectパターン / デザインパターン・メーリングリスト
2001年5月31日(木) 00:00Null Object(ナル・オブジェクト)パターンのお話をしましょう。
以下のNullOutputStreamクラスは 「writeしても実際には何も処理しない」クラスです。
NullPrintStreamクラスはNullOutputStreamクラスを使って 「printlnしても実際には何も処理しない」クラスです。
Applicationクラスは「0〜9までの整数を合計する」という 処理を行うアプリケーションです。
Mainクラスは、テスト動作用のクラスです。 オプション-dを使って起動するとデバッグプリントありになり、 -nを使って起動するとデバッグプリントなしになります。
デバッグプリントありのときはi=0〜9までの経過と結果を表示し、 なしのときは結果のみを表示します。
import java.io.*; class NullOutputStream extends OutputStream { public void write(int b) { // Do nothing } } class NullPrintStream extends PrintStream { public NullPrintStream() { super(new NullOutputStream()); } } class Application { private PrintStream debugout; public Application(PrintStream debugout) { this.debugout = debugout; } public void go() { int sum = 0; for (int i = 0; i < 10; i++) { sum += i; debugout.println("i = " + i); } System.out.println("sum = " + sum); } } class Main { public static void main(String[] args) { if (args.length == 0) { System.out.println("Usage: java Main -d --- for debug"); System.out.println("Usage: java Main -n --- not for debug"); System.exit(0); } if (args[0].equals("-d")) { new Application(System.out).go(); } else { new Application(new NullPrintStream()).go(); } } }
重要なのは、
debugout.println("i = " + i);
の部分です。 もしもデバッグプリントの有無をフラグなどで判断するとすると、 ここは、
if (debug) { debugout.println("i = " + i); }
になったり、あるいは、 デバッグプリントなしのときはdebugoutにnullを詰めることにして、
if (debugout != null) { debugout.println("i = " + i); }
のように判断するでしょう。もしかしたら、 もっと大胆に、
// debugout.println("i = " + i);
のようにコメントアウトするかもしれませんね (そして、出力するときにはコメントをはずすのです…やれやれ)。
でも、このNullPrintStreamのように「同じインタフェース(API)を持ちながら、 何も処理しないクラス」を作れば、 利用する側をシンプルにすることができます。
このようなデザインパターンを、Null Objectパターンと呼びます。
このデザインパターンはBobby Woolfによって提案されました (サンプルプログラム、および解説文は結城が考えたものです)。
デザインパターン・メーリングリストは22:00現在350人の参加者…。