2012-02-08 3 views
5

Supponiamo che tu abbia un oggetto che è unico e che è utilizzato da tutte le altre classi e funzioni ... qualcosa come $application.Metodo globale vs funzione vs classe statica

Come si accede a questo oggetto nelle proprie funzioni?

  1. utilizzando una variabile globale in ognuno di voi funzioni:

    global $application; 
    $application->doStuff(); 
    
  2. creazione di una funzione, come application() che crea un'istanza l'oggetto in una variabile statica e lo restituisce; quindi utilizzare questa funzione in tutto il mondo è necessario accedere all'oggetto:

    application()->doStuff(); 
    
  3. creare una cosa Singleton, come un metodo statico all'interno della classe di oggetti che restituisce l'unico caso, e utilizzare questo metodo per accedere all'oggetto:

    Application::getInstance()->doStuff(); 
    
  4. KingCrunch & skwee: Passare l'oggetto applicazione come argomento di ogni funzione/classe in cui è necessario

    ... 
    public function __construct(Application $app, ...){ 
        .... 
    

Se ci sono altre opzioni per favore pubblicali. Mi chiedo quale di queste opzioni sia la "best practice" più efficiente/considerata.

+2

Hai una domanda specifica o stai solo cercando di fare una lista? –

risposta

4

Lo passerei a tutti i metodi necessari. cioè

function doFoo(Application $app) { 
    $app->doStuff(); 
} 

Sia globale e Singleton considerato cattivo e cravatte il codice troppo e questo rende il test delle unità più difficile. C'è una regola quando si è permesso di utilizzare Singleton, se si risponde "sì" per la seguente dichiarazione:

Ho bisogno di introdurre lo stato globale per la mia domanda e devo avere una singola istanza di dato oggetto E avere più di un'istanza causerà errore

caso di risposta affermativa a tutte le 3 parti è possibile utilizzare Singleton. In ogni altro caso, passa tutte le istanze a tutti i metodi che ne hanno bisogno. Se si dispone di troppo di loro, considerare l'utilizzo di qualcosa come Context

class Context { 
    public $application; 
    public $logger; 
    .... 
} 
======== 
$context = new Context(); 
$context->application = new Application(); 
$context->logger = new Logger(...); 
doFoo($context); 
======== 
function doFoo(Context $context) { 
    $context->application->doStuff(); 
    $context->logger->logThings(); 
} 

(è possibile utilizzare getter/setter, se è necessario per proteggere i dati o manipolare o se si desidera utilizzare l'iniziazione pigro, ecc).

Buona fortuna!

+0

2 (Devo avere una singola istanza dell'oggetto dato) è un po 'vero :) – Alex

+0

Ma avere più di un'istanza causerà un errore nel programma? È un'affermazione logica di A && B && C, nel tuo caso B è vero e A e C false, quindi l'affermazione è falsa :) Non riesco davvero a pensare a una situazione in cui la risposta a questa affermazione sarà vera. Forse quando si programma una sorta di microcontrollore quando ho una singola CPU o qualcosa del genere ... –

1

O semplicemente darlo a quelli che ne sono interessati. Tutti i suggerimenti che hai fatto sono come variabili globali, anche se non lo chiami in 2 di 3 varianti.

Prima che si parli di questo: Se vuoi dire "Non è possibile, perché ha bisogno di tutto ciò che è", forse lo fa troppo, può fare troppo e/o sa troppo.

+0

Questo è vero, potrei passare l'applicazione come argomento per __costruire ogni classe in cui ne avevo bisogno. Ma non lo so ... L'uso di '$ this-> applicazione 'all'interno di quella classe sembra un po' strano – Alex

+0

anche io dovrei passare quell'argomento ad ogni metodo statico della classe ... – Alex

+0

Usando' $ this- > property' sembra esattamente come dovrebbe essere l'accesso ad una dipendenza. Per quanto riguarda il tuo secondo commento: Suoni, anche tu hai troppi metodi statici. – KingCrunch

4

Singleton, classi di Dio, classi monolitiche, ecc. Sono tutti modelli anti, quindi suggerirei una quarta opzione: iniezione di dipendenza. È possibile creare un'istanza di application nell'applicazione tramite una factory (o forse anche new se non ha dipendenze, ma questo può finire per complicare le cose in seguito).

Quindi, qualsiasi classe che abbia bisogno di accedere a application può ottenerla come membro, utile tramite il costruttore. Sono sicuro che non è necessario che ogni classe abbia accesso a application. Ricorda la legge di Demetra.

Se sono necessarie alcune funzionalità generiche come la conversione di una stringa statica in un'altra, suggerisco di utilizzare le funzioni globali di php (al contrario, ad esempio, di una classe statica faux). Credo che siano stati progettati per quello scopo.