Quindi, ci sono alcune buone risposte a questa domanda, vale a dire: Perché lo stato globale è così malvagio?
Ho una domanda specifica sulle alternative proposte da Mikera come risposta con il secondo voto più alto. Tutti sembrano essere dei buoni modi per evitare di usare lo stato globale, ma voglio sapere quale di queste alternative è la migliore delle prestazioni. Ovviamente questo dipende dalla lingua che stai usando, ma per la mia particolare domanda che sto chiedendo di JavaScript. Tuttavia, penso che questo potrebbe applicarsi ad altri linguaggi come Java.
Quindi, suppongo di avere una funzione JavaScript che chiama 10 funzioni JavaScript in serie (ad esempio, utilizzando la libreria asincrona Node.JS in un blocco async.series, le regole di scoping di async rendono tutto ciò ancora più difficile) e questo seriale l'operazione richiede variabili condivise per gestire lo stato dell'intera operazione. Questa informazione di stato non è più utile dopo il ritorno della funzione "genitore". Ora, si può evitare una parte della necessità di uno stato condiviso praticando un buon design durante la scrittura delle funzioni, ma nel mio caso specifico ho determinato che tutti hanno bisogno di leggere e modificare lo stato condiviso.
Quindi, posso seguire l'approccio di mikera e: Crea un'istanza di una nuova funzione ogni volta che questa funzione "genitore" viene chiamata utilizzando un functor per creare una chiusura, ad esempio:
function newFirstStep(sharedState)
{
return function firstStep(a,b)
{
//some logic with shared state
}
}
function parentFunction()
{
var sharedState = {"functionStartTime": 1400232233};
var step1 = newFirstStep(sharedState);
step1(1, 2);
}
o definire le funzioni all'interno della funzione genitore:
function parentFunction()
{
var sharedState = {"functionStartTime": 1400232233};
function step1(a,b)
{
//logic with shared state
}
step1(1,2);
}
La seconda opzione urla "male per il riutilizzo del codice", oltre a rendere difficile testare step1
.
L'altra alternativa è aggiungere un altro oggetto di contesto che passo ad ogni chiamata di funzione come altro argomento. Quando stavo cercando di capire come farlo prima, ho pensato che fosse estremamente goffo e brutto dover aggiungere un argomento extra per ogni variabile di stato condivisa a ogni singola funzione solo per avere lo stesso stato, ma avendo solo un singolo oggetto di contesto per suggerimento di mikera significa che devo solo aggiungere un argomento in più a ciascuna funzione. Questo è molto più appetibile. Tuttavia, "sente" inutilmente di dover passare questo dato che tutti "lo condividono". Forse sono troppo ossessionato da un dettaglio estremamente piccolo?
Ad ogni modo, ecco la mia domanda: Se utilizzo uno dei possibili modi per creare una chiusura (functor o define direttamente nella funzione parent), sembra estremamente inefficiente dover creare 10 nuove funzioni ogni volta chiamo questa funzione genitore. Voglio dire, il 95% delle funzioni è già definito. Questo sembra davvero inefficace ... e mi sentirei allo stesso modo di farlo in un linguaggio come Java (creando sempre nuove istanze di oggetti solo per ottenere uno stato condiviso).
Quindi, l'argomento del contesto è il migliore per quanto riguarda le prestazioni? Mi sto strappando i capelli cercando di decidere se usare o meno i funtori per ogni funzione o aggiungere un argomento oggetto contesto aggiuntivo a ogni firma di funzione perché nessuno sembra davvero una soluzione "grande". Mi sto concentrando su micro-micro-ottimizzazioni e devo solo concentrarmi sulla scrittura del codice ****?