В чем выгода вызова new для экземпляра объекта? - PullRequest
11 голосов
/ 25 октября 2009

Я читаю 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 для экземпляра объекта? Я предполагаю, что это то, для чего это, верно? Я предполагаю, что если кто-то захочет написать такой конструктор, ему придется добавить еще немного кода, который копирует атрибуты первого объекта в тот, который должен быть создан.

Ответы [ 3 ]

12 голосов
/ 25 октября 2009

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

В качестве примера, это полезно, когда у вас есть объекты ресурса, которые вам нужно сконструировать, когда возникает необходимость и стоимость вычислений КАКОГО типа объекта ресурса высока (скажем, длительный запрос к БД). Поэтому фабрика увидит, был ли ему передан старый ресурсный объект, и если это так, создайте такой же, как он, просто вызвав $old_object->new() - избегая затрат ресурсов на повторное вычисление вида ресурса.

В качестве другого примера, если у вас есть иерархия классов, обозначающая животных, и фабрика для конструирования новых животных в симуляции, вы можете вызвать $newborn = $factory->make_new_animal($mother) с реализацией фабрики, равной просто $object->new()

7 голосов
/ 25 октября 2009

Я не вижу никакой реальной пользы. Вы всегда можете просто сделать ref($obj)->new или иметь метод для выполнения $obj->clone; Таким образом, вы не задаетесь вопросом, что из этих двух $object->new делает.

5 голосов
/ 25 октября 2009

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

Что касается клонирования объектов, я обычно пишу явные методы clone () или copy (), которые могут правильно копировать атрибуты и другие данные, но нет никаких причин, почему new () не может позаботиться об этой роли, если это задокументировано ясно. Однако я вижу два преимущества в определении их отдельно:

  1. возможность использовать другой класс (ребенок или миксин / роль (например, роль лося)) для переопределения различного поведения
  2. возможность сделать код более понятным, например, если шаги, необходимые для создания нового "пустого" объекта, сильно отличаются от шагов, выполняемых при клонировании существующего объекта.
...