I'm reading Programming Perl
, and I found this code snippet:
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;
}
With constructors like this one, what's the benefit of calling new
on an object instance? I assume that it's what it's for, right? My guess is that if anyone would want to write such a constructor, he would have to add some more code that copies the attributes of the first object to the one about to be created.
So you can construct another object of the same class without knowing what the original class's object is - this can make for some really neat compact factory pattern.
As an example, this is useful when you have resource objects you need to construct, as need arises and the cost of computing WHICH kind of resource object is high (say, a long-running DB query). Therefore, a factory would see if it was passed an old resource object and if so, create one just like it by merely calling $old_object->new()
- avoiding the resource cost of re-computing the kind of resource.
As another example, if you have class hierarchy denoting animals, and a factory for constructing new animals in a simulation, you could call $newborn = $factory->make_new_animal($mother)
with the factory implementation being merely $object->new()
I don't see any real benefit. You can always just do ref($obj)->new
or have a method to do $obj->clone
; that way you aren't left wondering which of those two $object->new
is doing.
As others have said, it's to allow for the polymorphic creation of a new object instance without having to be aware of the type of that instance.
As for object cloning, I normally write explicit clone() or copy() methods that can properly copy attributes and other data over, but there's no reason why new() can't take care of this role, as long as it's documented clearly. However I see two advantages into defining them separately:
- being able to use a different class (a child, or a mixin/role (e.g. a Moose role)) to override various behaviour
- the potential of making the code clearer, such as if the steps required to create a new "empty" object is very different than those in cloning an existing object.
精彩评论