Il pattern Registry per non usare le variabili globali


Il pattern Registry per non usare le variabili globali

Il modo migliore per rendere disponibili certi valori e object a tutti i componenti di un’applicazione consiste nell’usare un singolo oggetto chiamato Registry, il cui compito, semplice ma utile, è storare e recuperare tutti quei dati di cui si richiese un accesso globale.
Il Registry stesso può essere passato come parametro o convertito in Singleton (speciali tipi di object che possono essere instanziati una volta sola) per permettere accesso globale allo stesso da qualsiasi punto dell’applicazione e semplificare il riutilizzo delle classi in applicazioni diverse.

Vediamo il semplice codice per generare il nostro Registry, questo esempio ci mostra un array privato che storerà gli objects e 4 metodi per registrare, cancellare, recuperare e controllare l’esistenza degli objects al suo interno.

class My_Registry { private $store = array();
public function __construct() {
}
public function register($label, $object) {
if(!isset($this->store[$label]))
{
$this->store[$label] = $object;
}
}
public function unregister($label) {
if(isset($this->store[$label]))
{
unset($this->store[$label]);
}
}
public function get($label) {
if(isset($this->store[$label]))
{
return $this->store[$label];
}
return false;
}
public function has($label) {
if(isset($this->store[$label]))
{
return true;
}
return false;
}
}

Dalla versione 5.1 di PHP possiamo servirci dei metodi di overloading per caricare gli oggetti dentro il Registry, semplificando così il pattern:

class My_Registry { private $store = array();
public function __construct() {
}
public function __set($label, $object) {
if(!isset($this->store[$label]))
{
$this->store[$label] = $object;
}
}
public function __unset($label) {
if(isset($this->store[$label]))
{
unset($this->store[$label]);
}
}
public function __get($label) {
if(isset($this->store[$label]))
{
return $this->store[$label];
}
return false;
}
public function __isset($label) {
if(isset($this->store[$label]))
{
return true;
}
return false;
}
}

che potremo poi utilizzare nella nostra applicazione in questo modo:

$reg = new My_Registry();
//nel caso di PHP 5.1 possiamo usare i metodi di overloading
//altrimenti useremo $reg->register(myObject) del primo esempio
$reg->myObject = new TipodiObject();
//recuperiamo il valore dell’object, se usiamo lo script del primo esempio useremo $reg->get(myObject)
$obj = $reg->myObject;
//restituisce un boolean, controlla se è settato il valore dell’object, caso primo esempio $reg->has(myObject)
isset($reg->myObject);
//restituisce un boolean ed elimina il valore dell’object, caso primo esempio $reg->unregister(myObject)
unset($reg->myObject);

Dal codice è facile notare che se è già presente un object con una specifica label (etichetta) nel Registry, questo non sovrascrive il primo ma continua come se non si fosse dichiarato nulla.

Cerca: , , , , , ,

Ritieni questo post utile o interessante?
Condividi e Segnala

Leggi anche:

4 commenti per “Il pattern Registry per non usare le variabili globali”

  1. Giuseppe ha detto:

    non capisco a cosa serve la dichiarazione del costruttore di classe se non si fanno operazioni?
    il codice non da possibilità di cambiare valori al registro con velocità, non converrebbe mettere una funzione che cambia il valore a tipo “ChangeValue(label,value)”?
    non capisco dove è l’utilità, non è semplicemente un array di valori?

  2. R.A.M.Page ha detto:

    La dichiarazione del costruttore è cosa che comunemente si fa quando si crea una classe, non è necessaria se non setta nulla o esegue operazioni ovviamente quindi puoi ometterla.

    Il codice non da la possibilità di cambiare valori al registro, certo, ma questo perchè è il pattern base per passare valori globali, valori poi che spesso sono intesi come costanti, tipo i parametri per l’accesso ad un database :)

    Se hai comunque bisogno di modificare i valori di un object settato puoi modificare la funzione pubblica “__set” togliendo l’IF condizionale così ogni volta che setterai una prorietà, se quella è già presente, la modificherai.

  3. Giuseppe ha detto:

    come mai allora non hai usato un array in un file separato come si usa nei CMS più comuni:
    es: joomla, postnuke, mambo? leggero e veloce e ha le stesse funzionalità.
    oppure se sono dati che sono fissi perchè non utilizzare costanti come accade in wordpress(vedo che lo utilizzi!).
    Non ho capito dove sta la convenienza in termini di velocità,semplicità,spazio occupato,strumentazione!!!

  4. R.A.M.Page ha detto:

    Non ho usato nulla in questo caso, ho semplicemente presentato un pattern molto usato per passare valori globali nelle web application PHP, ma non è assolutamente detto che questa sia la via migliore sempre e comunque…anzi, se sei programmatore anche tu saprai bene che i problemi non sono mai gli stessi e le soluzioni a volte dobbiamo semplicemente inventarcele…ma d’altronde è il problem solving il bello della programmazione, no? :)

    Premettendo che non ho mai usato Joomla, Postnuke o Mambo (a tanti sembrerà incredibile), forse parli di array scritti in file da includere nella pagina?
    In quel caso preferirei comunque un registry senza dovermi ricordare ogni volta di includere i file e soprattutto di andarli a cercare e poi cosa cambierebbe in termini di velocità e memoria?
    Però sicuramente sistemi collaudatissimi come Joomla o Postnuke avranno i loro buoni motivi per ricorrere ad inclusione di file, se sempre di questo si stava parlando..lo chiedo a te che probabilmente ci hai lavorato.

    Wordpress, per quello che ho visto, istanzia delle classi che recuperano valori, tipo quelli per la connessione al database, da variabili globali e poi si lavora con queste istanze..il Registry in questo un po’ gli somiglia, essendo una soluzione comune che consente a diversi oggetti di accedere ad altri oggetti senza il bisogno di passarli tutti come parametri individuali.
    Non credo ci sia una buona economia, se c’è poi, di memoria e risorse rispetto ai metodi da te citati ma secondo me questo pattern può essere una buona alternativa per chi non vuole sporcare troppo il codice.

Rispondi al post