2009-10-25 7 views
11

estoy leyendo Programming Perl, y me encontré con este fragmento de código:¿Cuál es la ventaja de llamar a alguien nuevo en una instancia de objeto?

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

con constructores como ésta, ¿cuál es el beneficio de llamar new en una instancia de objeto? Supongo que es para lo que es, ¿verdad? Mi suposición es que si alguien quisiera escribir tal constructor, tendría que agregar un código más que copie los atributos del primer objeto al que va a crear.

+0

Nota: una muy buena información en un Q relacionado: http://stackoverflow.com/questions/1621373/whats-the-benefit-of-calling-new-on-object-instance?rq= 1 – DVK

+0

Lol, estoy leyendo el mismo libro en este momento –

Respuesta

12

Así se puede construir otro objeto de la misma clase sin saber qué objeto de la clase original es - esto puede hacer por algún patrón de la fábrica compacta muy bien cuidado.

Como ejemplo, esto es útil cuando tiene objetos de recursos que necesita construir, según surja la necesidad y el costo de calcular QUÉ clase de recurso es alto (por ejemplo, una consulta DB de larga ejecución). Por lo tanto, una fábrica iba a ver si se pasa un objeto de recursos de edad y si es así, crear uno igual simplemente llamando $old_object->new() - evitando el costo de los recursos de la re-calcular el tipo de recurso.

Como otro ejemplo, si usted tiene la jerarquía de clases que denota animales, y una fábrica para la construcción de nuevos animales en una simulación, se podría llamar $newborn = $factory->make_new_animal($mother) con la implementación de la fábrica ser meramente $object->new()

+0

La función no copia nada de la instancia original. Simplemente obtiene el nombre de clase usando 'ref ($ self)', nada más. Después de eso, crea un objeto completamente nuevo. –

+0

Lucas - Sí, no leyó el código con el suficiente cuidado ... que pican los dedos :) He editado el "constructor de copia" de referencia por el momento en que se pronunciaron al respecto :) – DVK

+1

@DVK: tal vez podría mostrar un ejemplo? – ysth

7

no veo ningún beneficio real . Siempre puede hacer ref($obj)->new o tener un método para hacer $obj->clone; De esa forma no se preguntará cuál de esos dos $object->new está haciendo.

+0

ysth - ver mi respuesta. Hay algunas cosas geniales de fábrica que pueden implementarse si su clase base tiene este nuevo método de "hacer uno como yo". – DVK

+1

@DVK: mejor hecho con un método make_one_like_me, entonces. – ysth

+1

Se puede hacer -yes. "mejor" - discutible. Encuentro que ambos están bien, con el del libro más obvio y directo por un margen estrecho. – DVK

5

Como han dicho otros, es para permitir la creación polimórfica de una nueva instancia de objeto sin tener que ser consciente del tipo de esa instancia.

En cuanto a la clonación de objetos, normalmente escribo métodos explícitos clon() o copy() que pueden copiar atributos y otros datos, pero no hay razón por la cual new() no pueda ocupar este rol, siempre y cuando como está documentado claramente. Sin embargo veo dos ventajas en la definición de ellos por separado:

  1. ser capaz de utilizar una clase diferente (un niño, o un mixin/papel (por ejemplo, un papel Moose)) para anular diversos comportamiento
  2. el potencial de hacer el código más claro, como si los pasos necesarios para crear un nuevo objeto "vacío" son muy diferentes a los de clonar un objeto existente.
Cuestiones relacionadas