2009-10-25 13 views
11

Czytam Programming Perl i znalazłem ten fragment kodu:Jakie są zalety wywoływania nowego w instancji obiektu?

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; 
} 

Z konstruktorów podobny do tego, jaki jest zaletą nazywając new na instancji obiektu? Zakładam, że po to jest to, prawda? Domyślam się, że gdyby ktokolwiek chciał napisać taki konstruktor, musiałby dodać trochę kodu, który skopiuje atrybuty pierwszego obiektu do tego, który ma zostać stworzony.

+0

Uwaga: niektóre bardzo dobre informacje w powiązanym pytaniu: http://stackoverflow.com/questions/1621373/whats-the-benefit-of-calling-new-on-an-object-instance?rq= 1 – DVK

+0

Lol, czytam teraz tę samą książkę –

Odpowiedz

12

Można więc zbudować kolejny obiekt z tej samej klasy, nie wiedząc, jaki jest obiekt oryginalnej klasy - może to zrobić dla jakiegoś naprawdę zgrabnego wzoru fabryki.

Przykładowo jest to użyteczne, gdy masz obiekty zasobów, które musisz zbudować, w razie potrzeby i koszt przetwarzania, KTÓRYM rodzaj obiektu zasobu jest wysoki (powiedzmy, długo działające zapytanie DB). Dlatego fabryka zobaczyłaby, czy został przekazany stary obiekt zasobu, a jeśli tak, stwórz taki sam, nazywając tylko $old_object->new() - unikając kosztu zasobów ponownego obliczenia rodzaju zasobu.

Jako inny przykład, jeśli masz klasy hierarchii oznaczającą zwierząt oraz fabrykę buduje nowe zwierzęta w symulacji, można nazwać $newborn = $factory->make_new_animal($mother) z realizacją fabryka jest jedynie $object->new()

+0

Funkcja nie kopiuje niczego z oryginalnej instancji. Po prostu dostaje nazwę klasy używając 'ref ($ self)', nic więcej. Następnie tworzy zupełnie nowy obiekt. –

+0

Lucas - tak, nie przeczytał kodu wystarczająco uważnie ... swędzące palce :) Poprawiłem referencję "copy constructor" do czasu, kiedy ją skomentowałeś :) – DVK

+1

@DVK: może mógłbyś pokazać przykład? – ysth

7

nie widzę żadnej realnej korzyści . Zawsze możesz po prostu zrobić ref($obj)->new lub mieć metodę do wykonania $obj->clone; w ten sposób nie zastanawiasz się, który z tych dwóch $object->new robi.

+0

ysth - zobacz moją odpowiedź. Jest kilka naprawdę fajnych rzeczy, które mogą być zaimplementowane w fabrykach, jeśli twoja klasa bazowa ma tę nową metodę "make one like me". – DVK

+1

@DVK: lepiej zrobić przy użyciu metody make_one_like_me. – ysth

+1

Można to zrobić - tak. "lepsze" - dyskusyjne. Uważam, że oba są w porządku, a ten z książki jest bardziej oczywisty i lżejszy. – DVK

5

Jak powiedzieli inni, ma to umożliwić polimorficzne tworzenie nowej instancji obiektu bez konieczności bycia świadomym typu tej instancji.

Jeśli chodzi o klonowanie obiektów, normalnie piszę jawne metody clone() lub copy(), które mogą poprawnie kopiować atrybuty i inne dane, ale nie ma powodu, dla którego new() nie mógłby zająć tej roli, tak długo jak to jest jasno udokumentowane. Jednak widzę dwie zalety w określaniu ich oddzielnie:

  1. mogąc użyć innej klasy (A dziecko lub wstawką/rolę (np Moose ról)), aby zastąpić różnymi zachowanie ruchowe
  2. potencjał dokonywania kod jaśniejszy, na przykład jeśli kroki wymagane do utworzenia nowego "pustego" obiektu są bardzo różne od tych w klonowaniu istniejącego obiektu.
Powiązane problemy