11

我正在阅读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使用像这样的构造函数,调用对象实例有什么好处?我想这就是它的用途,对吧?我的猜测是,如果有人想编写这样的构造函数,他将不得不添加更多代码,将第一个对象的属性复制到即将创建的对象。

4

3 回答 3

12

因此,您可以在不知道原始类的对象是什么的情况下构造同一类的另一个对象——这可以形成一些非常简洁的紧凑型工厂模式。

例如,当您有需要构建的资源对象时,这很有用,因为需要并且计算哪种资源对象的成本很高(例如,长时间运行的数据库查询)。因此,工厂将查看是否传递了旧资源对象,如果是,则仅通过调用创建一个类似的资源对象$old_object->new()- 避免重新计算资源类型的资源成本。

再举一个例子,如果你有一个表示动物的类层次结构,以及一个用于在模拟中构建新动物的工厂,你可以调用$newborn = $factory->make_new_animal($mother)工厂实现仅仅是$object->new()

于 2009-10-25T16:56:53.870 回答
7

我没有看到任何真正的好处。你总是可以做ref($obj)->new或有方法去做$obj->clone;这样你就不会想知道这两个$object->new中的哪一个在做什么。

于 2009-10-25T18:11:21.377 回答
5

正如其他人所说,它允许多态地创建一个新的对象实例,而不必知道该实例的类型。

至于对象克隆,我通常会编写显式的 clone() 或 copy() 方法来正确复制属性和其他数据,但没有理由 new() 不能处理这个角色,只要它有明确的记录. 但是,我认为单独定义它们有两个优点:

  1. 能够使用不同的类(孩子,或 mixin/角色(例如 Moose 角色))来覆盖各种行为
  2. 使代码更清晰的潜力,例如如果创建一个新的“空”对象所需的步骤与克隆现有对象的步骤非常不同。
于 2009-10-25T18:25:17.400 回答