2012-08-14 18 views
5

Sto cercando di valutare le opinioni delle persone sull'uso di classi statiche invece di namespace. Vengo da uno sfondo C++ e sono abbastanza appassionato della sua sintassi e di come ti permette di strutturare il codice. Recentemente ho deciso che dovevo raggruppare il mio codice in unità logiche invece che solo file. Ad esempio preferisco le chiamate come User :: login a user_login. Così, ho fatto un po 'di google e sono stato sollevato nel constatare che PHP ha spazi dei nomi. Il mio sollievo non è durato a lungo però, davvero non mi piace la sintassi; aggiunge più disordine alle mie chiamate di funzione. Quindi, al momento sto usando le classi statiche per simulare i namespace. Ci sono degli aspetti negativi in ​​questo?PHP Static Class o Namespace

Ho trovato una domanda simile a PHP Namespaces vs Classes with static functions ma non c'era un sacco di discussione.

Inoltre, c'è un modo per evitare la seguente situazione:

class Test { 
public static void myFunc() { 
    Test::myOtherFunc(); 
} 
public static void myOtherFunc() { 

} 
} 

ho pensato che sarebbe stato ok per chiamare le funzioni della stessa classe senza specificare il nome, ma a quanto pare no. Ci sono soluzioni alternative per questo (ad esempio in C++ c'è la parola chiave using).

+0

'self ::' e '$ this->' sono utilizzati in PHP per chiamare rispettivamente i propri metodi statici e di istanza. –

+0

Quindi non è possibile che la qualifica sia implicita? vale a dire controllare la classe corrente per una funzione? – user1520427

+1

No, ma trovo che sia esplicito essere una buona cosa :) –

risposta

5

Casualmente Ho effettivamente sta muovendo nella direzione esattamente opposta:

  1. Usare i namespace per organizzare classi di dominio (o funzioni)
  2. Usa iniezione di dipendenza in cui avrei altrimenti utilizzati classi statiche

La cosa con le classi statiche per simulare gli spazi dei nomi è che non è possibile organizzarli su più file, tutto deve essere definito all'interno di un file; questo potrebbe anche essere all'altezza del gusto personale.

L'altra cosa sulle classi statiche è che si avvia senza stato e lentamente si insinua qualche gestione dello stato e si finisce con qualche strana dipendenza da lock-in. Lo stato dovrebbe essere riservato per le istanze. Attualmente la mia unica classe statica di rilievo è la configurazione a livello di sito.

Infine, l'autoreferenzialità nelle classi statiche è esplicita, mentre negli spazi dei nomi funziona esattamente come nel C++: si specifica il nome della funzione e prima viene cercato all'interno dello spazio dei nomi.

+0

Mi piace l'idea dei namespace e di come ti permettono di gestire il codice, come hai detto tu puoi organizzarli su più file. La mia unica vera lamentela è la sintassi sgraziata. Non vedo la necessità di usare \ e rimuovere la coerenza con altre lingue. – user1520427

+0

@ user1520427 So come ti senti, non è un grande osservatore, ma pensalo come una struttura di directory e ha senso :) il caricatore automatico predefinito in realtà lo usa anche in quel modo. –

4

Se si guarda dal punto di vista della struttura del codice, non c'è differenza tra il metodo di classe statica e la funzione di namespace. Entrambi finiscono in ambito globale. L'unica differenza è che, con il metodo di classe statico, si sta tentando di simulare OOP.

Perciò è meglio usare le funzioni di namespace, se ciò di cui si ha realmente bisogno sono funzioni standalone/utility. I namespace sono per il raggruppamento di cose (sia funzioni che classi).

Per quanto riguarda l'esempio User::login(), sarebbe una cattiva pratica. Invece dovresti avere un oggetto reale, che sia in grado di contenere lo stato.

$mapper = new UserMapper; 
$user = new User; 
$user->setNickname($name); 

$mapper->fetch($user); 

if ($user->hasPassword($password)) 
{ 
    $user->setLastLogin(time()); 
} 
else 
{ 
    // log the access attempt 
    // set error state 
} 

$mapper->save($user); 

La linea di fondo è questo: se si utilizza strutture statiche (funzioni o metodi), non è OOP. Stai solo fingendo. Invece dovresti usare OOP reale, con dependency injection.

Se il codice utilizza metodi statici e variabili dappertutto, causa un accoppiamento stretto tra le classi, aggiunge global state e rende harder to maintain and test il codice base. E questo non è specifico per PHP.