Меню

Главная
Случайная статья
Настройки
Null object (шаблон проектирования)
Материал из https://ru.wikipedia.org

В объектно-ориентированном программировании Null Object — это объект с определенным нейтральным («null») поведением. Шаблон проектирования Null Object описывает использование таких объектов и их поведение (или отсутствие такового). Впервые опубликован в серии книг Pattern Languages of Program Design.[1]

Содержание

Описание

В таких объектно-ориентированных языках как Java или C# объекты могут иметь значение NULL. Ссылки на такие объекты нуждаются в проверке на NULL-значение перед использованием, так как методы класса «нулевого» объекта, как правило, не могут вызываться.

Целью Null-object'а является инкапсулирование отсутствия объекта путём замещения его другим объектом, который ничего не делает.

Данный шаблон проектирования рекомендуется использовать, когда:
  • Объект требует взаимодействия с другими объектами. Null Object не устанавливает нового взаимодействия — он использует уже установленное взаимодействие.
  • Какие-то из взаимодействующих объектов должны бездействовать.
  • Требуется абстрагирование «общения» с объектами, имеющими NULL-значение.[2]


Плюсы
  • Снижаются шансы на ошибку — не произойдёт разыменование нулевого указателя, потому что его нет.


Минусы
  • Могут неоправданно включаться дополнительные механизмы языка программирования вроде выделения памяти и виртуального полиморфизма.
  • Если интерфейс сложный, нужно много нетворческого кода.
  • Если перед вызовом происходит сложная подготовка, всё равно приходится спрашивать у объекта, делает ли он что-то — но это лишь дополнительная оптимизация, не ведущая к моментальному отказу программы.
// Для ясности функции с разными сигнатурами зовутся разными именами.

// Тут никаких вопросов.
logger.put("Program started.");

// Запускается тяжёлый format, даже если журнала нет
logger.put(std::format("a={}, b={}", a, b));

// Тут format запускается, только если logger реально пишет
if (logger.isWriting()) {
  logger.put(std::format("a={}, b={}", a, b));
}

// Два способа решить, со своими достоинствами и недостатками
logger.format("a={}, b={}", a, b);
logger.putObj(LazyFormat{"a={}, b={}", a, b});


Структура

На диаграмме классов в языке UML шаблон проектирования представлен следующим образом:

Примеры

Пример на C#
/* 
 * Пример применения шаблона Null Object:
 */

void Main() 
{
	AbstractEntity realEntity = new RealEntity();
	realEntity.doSomething(); // RealEntity::doSomething
	
	AbstractEntity unknownEntity = new NullEntity();
	unknownEntity.doSomething(); // no output
}

// Define other methods and classes here
public abstract class AbstractEntity 
{
	public abstract void doSomething();
}

public class RealEntity : AbstractEntity 
{
	public override void doSomething() 
	{
		Console.WriteLine("RealEntity::doSomething");
	}
}

public class NullEntity : AbstractEntity 
{
	public override void doSomething() 
	{
		// doing nothing
	}
}


Пример на PHP
Downgrade Counter