Какая польза от вызова new на экземпляре объекта?
Я читаю Programming Perl
, и я нашел этот фрагмент кода:
sub new {
my $invocant = shift;
my $class = ref($invocant) || $invocant;
my $self = {
color => "bay",
legs => 4,
owner => undef,
@_, # Override previous attributes
};
return bless $self, $class;
}
С конструкторами, подобными этому, какое преимущество вызова new
в экземпляре объекта? Я предполагаю, что это за что, да? Я предполагаю, что если кто-то захочет написать такой конструктор, ему придется добавить еще один код, который копирует атрибуты первого объекта в тот, который будет создан.
Ответы
Ответ 1
Таким образом, вы можете создать другой объект того же класса, не зная, что такое исходный объект класса - это может сделать для некоторого действительно аккуратного компактного шаблона factory.
В качестве примера это полезно, когда у вас есть объекты ресурсов, которые необходимо построить, по мере необходимости, и стоимость вычисления. Какой-то ресурсный объект WHICH высок (скажем, долговременный запрос БД). Таким образом, factory увидит, был ли передан старый объект ресурса, и если да, создайте его так же, как он, просто назовите $old_object->new()
- избегая затрат ресурсов на повторное вычисление вида ресурса.
В качестве другого примера, если у вас есть иерархия классов, обозначающая животных, и factory для создания новых животных в симуляции, вы можете называть $newborn = $factory->make_new_animal($mother)
с реализацией factory просто $object->new()
Ответ 2
Я не вижу никакой реальной выгоды. Вы всегда можете просто сделать ref($obj)->new
или иметь способ сделать $obj->clone
; таким образом вам не остается задаться вопросом, какой из этих двух $object->new
делает.
Ответ 3
Как говорили другие, он допускает полиморфное создание экземпляра нового объекта без необходимости знать тип этого экземпляра.
Что касается клонирования объектов, я обычно пишу явные методы clone() или copy(), которые могут правильно копировать атрибуты и другие данные, но нет причин, по которым new() не может позаботиться об этой роли, пока это четко зафиксировано. Однако я вижу два преимущества в их определении отдельно:
- возможность использовать другой класс (дочерний элемент или роль mixin/role (например, роль Moose)) для переопределения различного поведения
- возможность сделать код более понятным, например, если шаги, необходимые для создания нового "пустого" объекта, сильно отличаются от тех, которые клонируют существующий объект.