Одно использование для метаклассов добавляет новые свойства и методы к экземпляру автоматически.
, Например, если Вы смотрите модели Django , их определение выглядит немного сбивающим с толку. Выглядит, как будто Вы только определяете свойства класса:
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
Однако во времени выполнения объекты Человека заполнены всеми видами полезных методов. Посмотрите источник для некоторого удивительного metaclassery.
Исходя из моего опыта, я не чувствую, что трудно поддерживать синхронизацию нулевого объекта. Если у вас есть эта проблема, у вашего объекта может быть слишком много обязанностей, так как он подвержен множеству изменений.
Я предпочитаю использовать этот шаблон, если я действительно могу определить такой объект с точки зрения обеспечения нормального поведения по умолчанию . Например, нулевой объект для манипуляции запросом - это объект, который не затрагивает исходный запрос. Нулевое расширение для другого объекта - это такое, которое ничего не делает.
Иногда я считаю, что это довольно чистый шаблон, позволяющий избежать проверки с помощью if для необязательного поведения, которое может существовать или не существовать в определенном состоянии моего приложения.
Если нулевое значение вашего объекта станет нормой для всего кода, вы также можете использовать шаблон. Я проверяю значение null, когда объект не был создан и его нужно создать . На самом деле я не использую null для чего-либо еще, и я, конечно, не использую его для обозначения отсутствия определенного поведения.
Однако если вы используете null, чтобы обозначить, что поведение еще не было определено или поведение по умолчанию - ничего , тогда обязательно используйте шаблон.
Я добился большого успеха, используя нулевые объекты с моими реализациями Factories и IoC. Они особенно полезны для вертикальных функций приложения. Я бы не стал создавать его для действия, которое является ядром вашего приложения.
Например, у вас есть интерфейс IPrinter и пара объектов, реализующих его - PrinterX и NullPrinter. При инициализации IPrinter вы можете попытаться запустить PrinterX, но если это не удастся, вместо этого вы вернете NullPrinter. В этом случае печать является функцией приложения, но не обязательным требованием для его успешной работы.
Я удостоверяюсь, что мои элементы IEnumerable
являются пустыми перечислениями вместо null
, но если чего-то действительно не хватает, что не так с null
? Иногда мне нужно различать неинициализированный и пропущенный в ситуации ленивой инициализации, но тогда я обычно использую отдельную логическую переменную для указания состояния, поэтому любое значение (включая null
) действительно для самого целевого объекта.