Примите ООП, удалите условные операторы и напишите более выразительный код

Паттерн Null Object — это тип шаблона, который сразу же кажется знакомым. Всякий раз, когда я показывал его кому-то, они сразу же проявляли интерес и чувствовали ценность его использования.

И это имеет большой смысл, undefined method for nil:NilClass, без сомнения, является ведущим исключением во всех приложениях на основе Ruby, и этот шаблон предлагает способ сделать их неактуальными.

Это также очень простой шаблон как для объяснения, так и для понимания.

Без лишних слов давайте посмотрим, что это такое, его приложения и как мы можем его реализовать.

Примечание. Мои примеры будут на предпочтительном для меня языке Ruby, но шаблон легко адаптируется к любому другому объектно-ориентированному языку. Те, у кого явный синтаксис объявления интерфейса, могут даже счесть его естественным.

Суть этого

Основная идея проста: всякий раз, когда вы пытаетесь ввести nil вместо значения, вместо этого вы возвращаете специально созданный объект: Null Object.

Этот нулевой объект будет иметь тот же интерфейс, что и добавленное вами значение, которое вы планируете вернуть (или, что более вероятно, только часть интерфейса), и поэтому он легко займет место исходного объекта в потоке вашего приложения. .

Пример

Давайте посмотрим, как мы можем это применить.

Исходная ситуация

В этом примере у нас есть простой класс Car, объекты которого регистрируются при инициализации для облегчения поиска в дальнейшем.

На данный момент, когда мы не можем найти Car в реестре, возвращается nil. Поэтому, если мы хотим что-то сделать с найденной машиной, мы получим либо ошибки NilClass, либо условные выражения с нулевой проверкой.

Вот когда появляется наш нулевой объект.

Замена nil объектом

Поэтому вместо того, чтобы позволить find_car возвращать nil, мы хотим, чтобы он возвращал предопределенный объект, который выглядит как Car.

Итак, мы создаем такой объект и сохраняем его в Car::Null (некоторые предпочитают иметь объект NullCar в другом месте, но мне нравится, когда он вложен), и мы настраиваем метод find_car.

Наш предыдущий пример теперь выглядит так:

Никаких условий, никаких ошибок. Разве жизнь не прекрасна.

Но что, если у нашей машины интерфейс больше, чем просто attr_readers?

Хорошо. Давайте позволим автомобилям описывать себя вместо наших puts вызовов.

И теперь мы настраиваем наш Null Object:

Идти дальше

Ваш нулевой объект не обязательно должен быть одним предопределенным объектом с неизменяемыми свойствами. Например, если мы хотим отобразить номерной знак нашей пропавшей машины, мы можем инициализировать с их помощью наши нулевые объекты.

Это начинает казаться довольно длинным определением этого нулевого объекта, не станут ли мои классы нечитаемыми?

Они действительно могут. Поэтому в некоторых случаях их лучше извлечь в отдельный файл, который можно найти, например, в папке nulls в вашем приложении.

Надеюсь, это поможет вам избавиться от этих ошибок undefined method on nil:NilClass!