Nullオブジェクトパターン……

オブジェクトの深いところの値を例外出す可能性無しにとってきたいで、ラムダ式使ってメンバがNULLでも例外出さずに画面へ出力できるような仕組みについて書いたんですが、「ドメイン駆動」に、そのまんまなケースが紹介されてました。推奨されてる解決方法は"Null オブジェクト"を使う、というもので、P122から引用すると

NULL オブジェクトパターンとは、nullを使う代わりに空インスタンス(空とはメンバの値がすべてデフォルト値だということを意味する。たとえば、 stringメンバの値はstring.Emptyになっている)を使うということだ。こうすれば、次のようなコードの"ドットをたどる"ことが確実にできる。

なるほどー、ということで、ビューモデルなんかはこれを利用して設計するのがよさそうですね、なのかなーと思いますが、"NULLオブジェクトパターン"で検索するとちょっとニュアンスの違う記述が見つかります。

でも、このNullPrintStreamのような 「同じインタフェース(API)を持ちながら、何も処理しないクラス」 を使えば、 条件判断が不要になり、利用する側をシンプルにすることができます。

出力の有無をコントロールするには、 Applicationに渡すOutputStreamを変えます。 つまり、Applicationのソースコードの修正を行わずに、 出力の有無を制御できることになります。

このような、 何も処理を行わないクラスを利用したデザインパターンを、Null Object(ナル・オブジェクト)パターンと呼びます。

"何も処理を行わない"と、"メンバの値がすべてデフォルト値"だとだいぶ意味が違うので、これはどういうことなのかなー、と思いますが、どちらも、もともとは96年に書かれたWoolfさん?の「The Null Object Pattern(Postscriptをgzしたファイルです)」という論文が出典みたいです。

英語だしSmalltalkだしでよくわかりませんでしたが、例として出されているのは上のケースとは逆というか、MVCパターンで、入力がない、読み取り専用のViewは Controllerをもつ必要ないのでControllerにNullオブジェクトを使うという感じなのかな、と思いました。そのほかの部分は結城さんの説明が近い気がします。冒頭で引用した部分は、この文脈でNullオブジェクトパターン使うといったら、空のインスタンス使うってことやで、くらいの感じなのか。

ちなみに、「エンタープライズ アプリケーションアーキテクチャパターン」にもNullオブジェクトはでてくるのですが、こちらでは"スペシャルケース"という「特定のケースで特別な振る舞いを提供するサブクラス」の一例として紹介されてます。こちらの例は「ドメイン駆動」のものに近いです。「ドメイン駆動」では実装方法まで触れていないというか、"空インスタンス"を使うと言ってるので同じクラスでメンバだけ空に設定されたインスタンス、のようにも読めるような気がしますけど、パターンと言ってる時点でそういうクラスを利用するにきまってるやろ!! ということなのだろうか……。