夜 - 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人の参加者…。