Один из вариантов - не проверять наличие статуса, предоставляя всем контактам (при создании контакта) статус по умолчанию, который ничего не делает.
Вы могли бы назвать это идиомой Null Object: объект, который вы используете там, где вы в противном случае использовали бы null (C, C ++, Java) или NULL (SQL) - это фактически то, что Smalltalk делает с nil; nil - это специальный объект, экземпляр класса UndefinedObject.
Преимущество этой идиомы состоит в том, что вам не нужно проверять и иметь специальную обработку для условия "объект не существует". Это делает код более чистым и более объектно-ориентированным, поскольку ваш экземпляр Null Object, а не вызывающий код, может определять, что делать при вызове его методов.
Вот пример Java, использующий шаблон цепочки ответственности. Chain of Responsibility в основном означает наличие списка обработчиков , каждый из которых обрабатывает что-то (команда ) или передает его следующему обработчику в цепочке. Мы сделаем обработчик Null Object, который просто ничего не делает, когда его просят что-то обработать.
Во-первых, генподряд:
interface Handler {
void handle( Command c ) ;
}
Тогда Нулевой Обработчик с (ужасом!) Синглтоном:
class NullHandler implements Handler {
public static void NullHandler singleton = new NullHandler();
void handle( Command c ) { /*no-op*/}
}
Затем базовый класс для любого другого типа обработчика (здесь также используется шаблонный шаблонный шаблон, но это просто деталь реализации):
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 ) ;
. Но когда мы добавляем больше кода, значение становится более очевидным.
Допустим, мы хотим напечатать нашу Цепочку ответственности. Один из способов сделать это - выполнить внешнюю итерацию цепочки в нашем коде, каждый раз проверяя, есть ли next == null.
Но лучше, более объектно-ориентированный, мы можем позволить Цепи делать это самостоятельно. Опять же, при печати BaseHandler
мы напечатали имя этого экземпляра, а затем вызвали метод печати next
. Метод print
в NullHandler ничего не выводит, или, возможно, «конец цепочки».