1 つのオプションは、(連絡先が作成されたときに) すべての連絡先に何もしない既定の状態を与えることによって、状態の存在を確認する必要がないことです。
これを Null オブジェクトのイディオムと呼ぶことができます。つまり、通常は null (C、C++、Java) または NULL (SQL) を使用する場所で使用するオブジェクトです。実際、これは Smalltalk が nil に対して行うことです。nil は UndefinedObject クラスのインスタンスである特別なオブジェクトです。
このイディオムの利点は、「オブジェクトが存在しない」状態をチェックしたり、特別な処理をしたりする必要がないことです。これにより、よりクリーンなコードが作成され、よりオブジェクト指向にもなります。これは、呼び出しコードではなく Null オブジェクト インスタンスが、そのメソッドが呼び出されたときに何をすべきかを決定できるためです。
以下は、Chain of Responsibility パターンを使用した Java の例です。責任の連鎖とは基本的に、それぞれが何か (コマンド) を処理するか、チェーン内の次のハンドラに渡すハンドラのリストを持つことを意味します。何かを処理するように求められたときに何もしない Null オブジェクト ハンドラを作成します。
まず、一般契約:
interface Handler {
void handle( Command c ) ;
}
次に、(恐ろしい!)シングルトンを備えたNull Handler:
class NullHandler implements Handler {
public static void NullHandler singleton = new NullHandler();
void handle( Command c ) { /*no-op*/}
}
次に、他のすべての種類の Handler の基本クラス (これもテンプレート メソッド パターンを使用します。バストは単なる実装の詳細です):
abstract class BaseHandler implements Handler {
private Handler next;
public BaseHandler( Handler next ) {
this.next = next ;
}
public BaseHandler() {
this( NullHandler.singleton ) ;
}
public void handle( Command c ) {
if( canHandle( c ) {
doHandle( c ) ;
} else {
next.handle( c ) ;
}
}
//Template Method hooks
abstract boolean canHandle( Command c ) ;
abstract void doHandle( Command c ) ;
}
したがって、ここで得られるものは限られていnext.handle( c ) ;
ますif next != null next.handle( c ) ;
。しかし、コードを追加するにつれて、その価値はより明確になります。
責任の連鎖を印刷したいとしましょう。これを行う 1 つの方法は、コード内で Chain の反復を外部化し、毎回 next == null かどうかをテストすることです。
しかし、より良いことに、よりオブジェクト指向的に、Chain 自体に任せることができます。の printでは、そのインスタンスの名前を出力してから、の print メソッドBaseHandler
を呼び出します。NullHandlernext
のメソッドは何も出力しないか、おそらく「チェーンの終わり」を出力します。print