2011-01-11 14 views
26

Come dice il titolo, sto cercando di creare un'istanza di una classe all'interno di un metodo statico della stessa classe. Ho capito finora che posso fare qualcosa di simile a questo:Creare un'istanza di classe dal metodo statico

class Foo{ 

public $val; 

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

} 

Che quindi mi consente di fare questo.

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

Che è fantastico.

Quindi ora le domande. C'è un modo più semplice per farlo di cui non sono a conoscenza, o qualche scorciatoia per ottenere lo stesso risultato? Ci sono dei vantaggi o degli svantaggi nel creare un'istanza in questo modo?

Grazie.

+2

Qual è il motivo per farlo in questo modo? Perché non usare plain '$ obj = new Foo (" qualche variabile ");'? –

+1

Non ha senso per me creare qualcosa con il costruttore che è già stato creato ad un certo punto. Ad esempio, in un progetto corrente, utilizzo Profile :: get() per caricare un profilo che (a un certo punto) è già stato "costruito". Forse sto abusando del costruttore o usando questo come una risposta al sovraccarico. – daniel

risposta

68

Il modo in cui lo state facendo va bene. Ci sono alcune altre cose che possono semplificarti la vita che puoi fare anche tu.

  1. Non inserire il codice di classe nel codice. Se hai più di 5.3 anni, utilizza la parola chiave static. In questo modo, se si estende la classe, la nuova funzione può istanziare che uno così:

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

    Quindi è possibile utilizzare in qualsiasi classe che estende senza bisogno di sostituire nulla.

  2. Verificare se $var deve essere passato attraverso un costruttore piuttosto che dopo la costruzione. Se l'oggetto dipende da questo, dovresti richiederlo.

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

    In questo modo non è possibile creare un'istanza dell'oggetto senza impostare la variabile.

  3. Applicare l'istanza della classe tramite il metodo statico. Se stai facendo qualcosa che devi fare, allora rendi il costruttore protetto o privato. In questo modo, qualcuno non può ignorare il metodo statico.

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

Mi auguro che aiuta ...

Modifica: Sulla base del tuo commento sopra, mi sembra che tu stia cercando di implementare lo Singleton Design Pattern. Ci sono un sacco di informazioni là fuori sul perché non è una grande idea e le cose cattive che può fare. Ha anche usi.

Ma ci sono alcuni altri schemi che potrebbero esserti utili a seconda di cosa stai facendo esattamente.

  • È possibile utilizzare lo Factory Method se si sta tentando di creare oggetti diversi con gli stessi passaggi.
  • Se tutti gli oggetti iniziano allo stesso modo e sono personalizzati, è possibile utilizzare Prototype Pattern.
  • È possibile utilizzare uno Object Pool se è particolarmente costoso creare il proprio oggetto.

Ma una cosa da considerare, è che in PHP gli oggetti sono piuttosto leggeri. Non cercare di evitare di creare un nuovo oggetto solo per quel sovraccarico. Evita di fare cose pesanti come query di database o accessi al filesystem più volte. Ma non preoccuparti di chiamare new Foo() a meno che il costruttore di foo sia particolarmente pesante ...

0

Se si sta solo creando un oggetto, questo non è molto utile. Potresti semplicemente chiamare un costruttore. Ma se stai facendo qualcosa di più complicato (come se stessi iniziando con una sorta di modello singleton ma non includessi tutti i dettagli in questo esempio), allora:

Questo suona bene. Se si vuole evitare che gli oggetti creati in modo predefinito come questo:

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

È possibile aggiungere un costruttore privato:

class Foo{ 

public $val; 

private __construct(){} 

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

Ora è far rispettare le persone di utilizzare la classe statica. La necessità di impostare la val nella funzione potrebbe essere sparita, quindi potresti anche aggiungere il parametro value al tuo costruttore privato ma fai le altre cose (che presumibilmente vuoi fare, come controllare una sorta di pattern singleton) nel tuo Funzione 'bar'

3

Sembra un semplice metodo di metodo di fabbrica.

Hai un bel vantaggio: supponiamo che in futuro si voglia iniziare a utilizzare un'implementazione diversa (ma che fa la stessa cosa). Usando una fabbrica puoi cambiare tutti gli oggetti che sono creati in molti posti di un sistema complesso semplicemente cambiando il metodo creatore. Si noti che ciò funzionerebbe più facilmente se si fosse utilizzata una classe esterna (come nel primo collegamento sottostante).

Mantenendolo come ora, è anche possibile creare una sottoclasse di questa classe e sovrascrivere il metodo per creare un oggetto più complesso. Non penso che questo sia ciò che vuoi ottenere qui.

In ogni caso, questo è utile per consentire lo sviluppo di Test Driven, l'astrazione e molte altre cose positive.

link:

  1. Php patterns
  2. Factory method pattern on wikipedia
Problemi correlati