2011-01-11 16 views
26

Como dice el título, quiero crear una instancia de una clase desde un método estático de la misma clase. He descubierto hasta ahora que puedo hacer algo como esto:Crear instancia de clase desde el método estático

class Foo{ 

public $val; 

public static function bar($val){ 
    $inst = new Foo; 
    $inst->val = $val; 
    return $inst; 
} 

} 

Que, por tanto, me permite hacer esto.

$obj = Foo::bar("some variable"); 

¿Qué es genial.

Así que ahora las preguntas. ¿Hay alguna manera más fácil de hacer esto de la que no tengo conocimiento, o cualquier atajo para lograr el mismo resultado? ¿Hay alguna ventaja o desventaja de crear una instancia de esta manera?

Gracias.

+2

¿Cuál es su razón para hacerlo de esta manera? ¿Por qué no usar plain '$ obj = new Foo (" some variable ");'? –

+1

No tiene sentido para mí crear algo con el constructor que ya se haya hecho en algún momento. Por ejemplo, en un proyecto actual, uso Profile :: get() para cargar en un perfil que (en algún momento) ya se ha "construido". Tal vez estoy haciendo un mal uso del constructor o usándolo como una respuesta a la sobrecarga. – daniel

Respuesta

68

La forma en que lo está haciendo está bien. Hay otras cosas que pueden hacer que su vida sea más fácil que usted también.

  1. No codifique el nombre de la clase. Si usa 5.3 o superior, use la palabra clave static. De esta manera, si se amplía la clase, la nueva función se puede crear una instancia que uno así:

    public static function bar($var) { 
        $obj = new static(); 
        $obj->var = $var; 
        return $obj; 
    } 
    

    A continuación, se puede utilizar en cualquier clase que se extiende sin necesidad de anular cualquier cosa.

  2. Averigüe si $var se debe pasar a través de un constructor en lugar de establecer después de la construcción. Si el objeto depende de él, debe requerirlo.

    public function __construct($var) { 
        $this->var = $var; 
    } 
    

    De esa manera no puede crear una instancia del objeto sin establecer la variable.

  3. Imponga la creación de instancias de la clase a través del método estático. Si está haciendo algo allí que necesita hacer, entonces haga que el constructor sea protegido o privado. De esa forma, alguien no puede eludir el método estático.

    protected function __construct() {} 
    private function __construct() {} 
    

Espero que ayude ...

Editar: Basado en su comentario anterior, me parece que está tratando de implementar el Singleton Design Pattern. Hay un montón de información sobre por qué no es una gran idea y las cosas malas que puede hacer. Tiene usos también.

Pero existen otros patrones que pueden serle útiles según lo que esté haciendo exactamente.

  • Puede usar el Factory Method si está intentando crear diferentes objetos utilizando los mismos pasos.
  • Si todos los objetos comienzan igual y luego se personalizan, puede usar Prototype Pattern.
  • Puede usar Object Pool si es particularmente costoso crear su objeto.

Pero una cosa a tener en cuenta, es que en PHP los objetos son bastante livianos. No intente evitar la creación de un nuevo objeto solo por esa sobrecarga. Evite hacer cosas pesadas como consultas de bases de datos o accesos al sistema de archivos varias veces. Pero no se preocupe por llamar al new Foo() a menos que el constructor de foo sea particularmente pesado ...

0

Si solo está creando un objeto, esto no es muy útil. Podrías simplemente llamar a un constructor. Pero si estás haciendo algo más complicado (como que comiences con algún tipo de patrón singleton pero no has incluido todos los detalles en este ejemplo), entonces:

Esto suena bien. Si desea evitar que los objetos creados en el modo por defecto como esto:

$obj = new Foo("Some Variable"); 

Se puede añadir un constructor privado:

class Foo{ 

public $val; 

private __construct(){} 

public static function bar($val){ 
    $inst = new Foo; 
    $inst->val = $val; 
    return $inst; 
} 
} 

Ahora se hacen cumplir a la gente a usar su clase estática. La necesidad de establecer el valor en la función puede haber desaparecido, por lo que incluso podría agregar el parámetro de valor a su constructor privado, pero hacer las otras cosas (que presumiblemente desea hacer, como verificar algún tipo de patrón de singleton) en su función 'bar'

3

Esto parece un patrón de método de fábrica simple.

Tiene una buena ventaja: suponga que en el futuro desea comenzar a utilizar una implementación diferente (pero que hace lo mismo). Usando una fábrica puede cambiar todos los objetos que se crean en muchos lugares de un sistema complejo simplemente cambiando el método del creador. Tenga en cuenta que esto funcionaría más fácilmente si utilizara una clase externa (como en el primer enlace a continuación).

Manteniéndolo como ahora, también puede subclase esta clase y anular el método para crear un objeto más complejo. No creo que esto sea lo que quieres lograr aquí.

De todos modos, esto es bueno para permitir el desarrollo impulsado por prueba, la abstracción y muchas otras cosas buenas.

enlaces:

  1. Php patterns
  2. Factory method pattern on wikipedia
Cuestiones relacionadas