2013-07-04 16 views
6

Sono un po 'incerto sull'uso corretto dei metodi statici in PHP.Uso corretto di "getInstance" e metodi statici in PHP?

Nello scenario di seguito:

<?php 

class Person 
{ 
    public $data; 

    public function __construct($id) 
    { 
     // Fetch record from our data source 
     switch($id){ 
      case 1: 
       $this->data = array('id'=>1, 'name'=>'Mike'); 
       break; 
      case 2: 
       $this->data = array('id'=>2, 'name'=>'Jennifer'); 
       break; 
      default: 
       exit('Record not found!'); 
     } 
    } 

    public function getName() 
    { 
     return $this->data['name']; 
    } 

    public static function getInstance($id) 
    { 
     return new self($id); 
    } 
} 

?> 

Ho poi uscita i nomi "Mike" e "Jennifer":

Esempio A

<?php 

foreach(array(1,2) as $id) 
    echo Person::getInstance($id)->getName(); 

?> 

Esempio B

<?php 

foreach(array(1,2) as $id){ 
    $person = new Person($id); 
    echo $person->getName(); 
} 

?> 

O stamperà "MikeJennifer", ma mi è stato detto L'esempio A è errato, "perché Persona non è una classe statica".

Una classe non può essere dichiarata "statica" in PHP, quindi perché dovrebbe essere importante?

+1

"ma mi è stato detto che l'Esempio A è sbagliato" --- non lo è. La persona che te l'ha raccontata ha torto. – zerkms

+2

Perché la persona sbaglia? Il primo frammento sembra uno schema singolo. In questo caso non sembra essere necessario ... –

+0

Questa classe consentirebbe comunque istanze multiple. Quindi sembra una brutta implementazione di un Singleton. Una sorta di classe ibrida – tlenss

risposta

3

In "Emergent Design", Scott L Bain descrive questo come un primo passo per l'astrazione della creazione di oggetti.

Giorno 1: Nessun astrazione ...

$person = new Person($id); 

2 ° giorno: un metodo statico per costruire l'oggetto per voi ...

$person = Person::getPerson($id); 

Perché? Perché ora hai solo un pezzo di codice nella tua intera applicazione che sa come "rinnovare" una persona, piuttosto che avere molte righe di codice distribuite tra l'intera applicazione che hanno questa conoscenza. Se cambi la modalità di costruzione di un oggetto persona in futuro, sarai in grado di modificare semplicemente il metodo statico getPerson.

Giorno 3+: è possibile decidere di appoggiarsi a un object builder o repository per la creazione dell'oggetto. Quando si sceglie di farlo, è possibile aggiornare il metodo statico getPerson per utilizzare il builder/repository e ancora una volta il cambiamento avviene in un unico punto.

Questo è chiamato "coesione". Avere codice in cui è possibile apportare modifiche senza dover aprire molti file.

+0

Per non essere d'accordo, questo sembra interessante, ma qual è la differenza tra alterare il metodo 'getPerson' e solo alterare il costruttore' Persona'? –

+0

@Wesley Murch: questo può far luce: http://en.wikipedia.org/wiki/Builder_pattern – zerkms

+1

Se si utilizza 'new Person ($ id)' in tutto il codice (diciamo, 20 volte) è necessario modificare il costruttore 20 volte. Usando 'Person :: getPerson ($ id)' non devi cambiare quel codice. Per esempio, se avessi bisogno di passare una dipendenza in 'nuova Persona 'non avrei dovuto creare e passare la dipendenza in 20 posti, solo uno. – Fenton