Singleton in WordPress, rivisitati (un’ora e un luogo?)
Prima di iniziare un post in cui si parla dell’utilizzo dei singleton in WordPress (o, più appropriatamente, del Singleton Pattern ), voglio assicurarmi che tu legga i seguenti due articoli:
- Clonazione in PHP, o perché il tuo singleton potrebbe uccidere WordPress di Thomas Scholz
- Singleton e loro utilizzo in WordPress di Carl Alexander
Entrambi questi articoli forniscono una prospettiva immensamente preziosa su questo modello e sui pericoli del suo utilizzo ogni volta che lo si utilizza durante il nostro lavoro in WordPress; tuttavia, significa che dovremmo evitarli completamente?
Non credo.
Poi di nuovo, riconosco anche che gli articoli non dicono di evitarli completamente. Stanno fornendo casi forti su come usarli e sui pericoli del loro utilizzo se si sceglie di farlo.
E sebbene li abbia sicuramente usati in passato, generalmente ho smesso. Tuttavia, di recente mi sono imbattuto in un caso d’uso per un progetto in cui penso sia accettabile.
Utilizzi ancora singleton in WordPress?
Per dare una ragione sul perché considero questo modello particolare, penso che valga la pena prima capire il caso d’uso. Per dirla semplicemente:
- C’è una pagina di amministrazione che consente all’utente di selezionare come desidera visualizzare le date sul front-end del sito.
- Quando l’utente salva l’opzione, scriverà il formato basato su PHP per la data in una tabella in WordPress.
- Quando si esegue il rendering di una data, il valore verrà recuperato dal database e applicato alla data di cui eseguire il rendering.
E per coloro che sono curiosi, ci sono solo una manciata – diciamo quattro o cinque – modi in cui consentiamo all’utente di visualizzare la data.
Poiché questo particolare progetto consente agli utenti di importare CSV di dati (che includono date) e ciò consente loro di eseguire il rendering dei dati dai CSV anche se in un formato diverso, vale la pena notare che c’è una discreta quantità di formattazione della data che si verifica sul back-end.
Naturalmente sorge una domanda:
Perché non formattare semplicemente la data in cui l’utente importa il proprio CSV?
E questo perché l’utente può scegliere di modificare il modo in cui viene visualizzata la data dopo l’importazione del CSV.
Detto questo, c’è tutto questo altro meccanismo nel plug-in responsabile della convalida, della sanificazione e della scrittura dell’input dell’utente nel database.
Ma quando arriva il momento di acquisire valori dal database, specialmente quando si tratta di leggere un valore da una tabella di database, e farlo in più punti dell’applicazione, non avrebbe senso avere un singolo punto da quale valore si può ricavare?
Uno sguardo ad alto livello su come funziona.
Oppure, in un altro modo, non ha senso cambiare una posizione nell’applicazione che può facilmente sovrapporsi al resto dell’applicazione piuttosto che cercare tutte le possibili posizioni di:
- leggendo l’opzione,
- assicurandosi che sia impostato,
- definire un default se non è impostato,
- e restituire il valore?
Ed è qui che vedo entrare in gioco un valido uso di un singleton in WordPress: un modo per leggere i dati in più punti dell’applicazione. Ciò comporta, tuttavia, alcune implicazioni:
- la classe non ha bisogno di essere istanziata più di una volta (voglio dire, questa è l’intera idea del singleton),
- non avrà a che fare con dati mutevoli,
- non scriverà informazioni o manipolare informazioni.
In altre parole, è l’unico responsabile del recupero delle informazioni e della restituzione. Questo è tutto. Nient’altro.
Un esempio di implementazione
Allora come potrebbe essere? Ecco un’implementazione approssimativa ai fini della conversazione:
<?php
class Date_Formatter {
private static $instance;
private function __construct() {
}
private static function get_instance() {
if (null === self::$instance) {
self::$instance = new self;
}
return self::$instance;
}
public static function get() {
self::get_instance();
$default_format = 'm/d/Y';
$format = get_option( 'yhd_directory_importer', false );
if (false === $format) {
return $default_format;
}
$format = $format['date'];
$format = (isset( $format) && isset( $format['format']) )? $format['format']: $default_format;
return $format;
}
}
Come puoi vedere, soddisfa tutti i punti sopra. Cioè, legge i dati, imposta un valore predefinito e quindi lo restituisce.
Questa classe non fa altro che leggere e restituire un insieme di dati molto specifico.
Un avvertimento sulla memorizzazione nella cache
Ovviamente, poiché questa classe sta leggendo i dati dal database, può essere – e forse dovrebbe essere – memorizzata nella cache. Il punto di questo post, tuttavia, non è entrare nei transitori, nelle scadenze e nell’elaborare tutte queste sfumature.
Si tratta invece di valutare se questo è un caso d’uso valido per l’implementazione di un singleton in WordPress.
Aspetta, non deve essere così!
Lo so, lo so. Psichico! Credo sia la terminologia corretta, ma manteniamo questo aspetto professionale.
Fino a questo punto, l’intero post ha parlato del motivo per cui potresti voler indagare sull’utilizzo dei singleton in WordPress in modo da avere un modo per recuperare facilmente le informazioni utilizzando principi costantemente orientati agli oggetti.
Ma non penso ancora che l’uso di un singleton in WordPress sia necessario qui. Per lo meno, penso che una funzione statica vada bene. E l’unico motivo per cui penso che vada bene è perché creare un’istanza della classe ogni volta che è necessario accedere a una funzione che recupera dati che non cambieranno all’interno della classe è eccessivo.
Allora com’è questo aspetto?
<?php
class Date_Formatter {
public static function get() {
$default_format = 'm/d/Y';
$format = get_option( 'yhd_directory_importer', false );
if (false === $format) {
return $default_format;
}
$format = $format['date'];
$format = (isset( $format) && isset( $format['format']) )? $format['format']: $default_format;
return $format;
}
}
E questa, credo, sia una soluzione migliore rispetto all’implementazione di un modello di progettazione arbitrario quando non è affatto necessario.
Ma sono aperto ad essere convinto del contrario.
Pensieri di sviluppatori più esperti?
Ho sentito da un altro amico e collega che semplicemente usare una funzione con spazio dei nomi potrebbe anche essere la strada da percorrere. Chiaramente, ci sono una varietà di modi per affrontare questo.
E con questo, sono interessato a sentire dal resto di voi come potresti riformulare ulteriormente questo aspetto. Non sono molto interessato all’implementazione della funzione get poiché è principalmente messa insieme per la demo.
Invece, sono interessato a modi per gestirlo al di fuori di ciò che viene presentato qui. O, meglio, solo la tua opinione su ciò che vedi.