Примите ООП, удалите условные операторы и напишите более выразительный код
Паттерн 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
!