Accumulate and fire
# Accumulate and fire

Accumulate and fire è un termine inglese (reso approssimativamente dall'espressione «carica e spara») che denota uno specifico stile di programmazione.

Lo stile Accumulate and fire è caratterizzato dalla presenza di istruzioni che aggiornano un certo numero di variabili globali od oggetti prima di invocare una subroutine o un metodo il cui funzionamento dipende da tali valori globali.

## Svantaggi

Di norma, questo stile di programmazione è considerato problematico per diversi motivi:

* il comportamento della subroutine che dipende da valori globali è meno trasparente, perché non tutti gli ingressi effettivi compaiono nella lista degli argomenti;
* a causa della visibilità globale delle variabili che contengono i valori di ingresso, la modifica di queste variabili può cambiare il comportamento di una parte del programma lontana dal punto della modifica (effetto di azione a distanza);
* il programma è maggiormente soggetto ad errori difficili da individuare, in quanto
   * è possibile dimenticarsi di modificare una certa variabile globale prima di un'invocazione,
   * l'effetto della mancata modifica può essere difficile da individuare e può causare malfunzionamenti in parti del programma distanti nel tempo;
* se l'esecuzione del programma procede in thread paralleli, vi è il rischio che lo stato di alcune delle variabili possa essere alterato da un altro thread in un istante posto tra la modifica dei valori e l'invocazione.

Nei casi peggiori, le variabili globali in questione sono definite al solo scopo di passare informazioni alla subroutine o al metodo invocato. In questi casi, l'informazione contenuta nelle variabili rischia di essere valida, aggiornata e significativa soltanto in un'area ristretta del programma, nel caso peggiore immediatamente prima delle invocazioni. In questi casi lo stato complessivo del programma è ambiguo, perché parzialmente indefinito in alcune aree e fasi di esecuzione del programma.

## Cause e motivazioni

Lo stile accumulate and fire è incoraggiato da alcuni fattori:

* la presenza di un gran numero di variabili globali per rappresentare lo stato del sistema;
* subroutine o metodi complessi e fortemente dipendenti dallo stato globale.

L'uso di variabili globali invece di argomenti espliciti è spesso motivato dalla volontà di evitare liste di parametri eccessivamente lunghe. La presenza di numerose variabili globali per rappresentare lo stato del programma può derivare dalla scarsa cura nel definire astrazioni valide per descrivere lo stato complessivo del sistema.

## Soluzioni

Il modo più semplice per evitare lo stile accumulate and fire consiste nel passare tutti i valori di ingresso delle subroutine, compresi quelli globali, come argomenti espliciti. Questo approccio, che spesso risulta poco pratico a causa del gran numero di argomenti da passare, non elimina le vere cause del problema. Per eliminare le cause che portano allo stile accumulate and fire è necessario intervenire più radicalmente sul programma. Un possibile approccio consiste nel raggruppare le variabili globali interessate in una struttura dati e quindi passare la struttura come argomento. Nell'ambito della programmazione a oggetti, la struttura dati può essere perfezionata in un oggetto facciata. Soluzioni di questo tipo sono opportune se i raggruppamenti sono dotati di coerenza interna, cioè i parametri globali sono inter-dipendenti o legati tra loro da relazioni logiche. Un altro approccio consiste nel suddividere la subroutine in subroutine più semplici, che richiedono solo alcuni degli argomenti.

Una soluzione diretta al problema di thread paralleli che modificano le stesse variabili globali in modo imprevisto prima di una invocazione consiste nell'introdurre un meccanismo di controllo dell'accesso, per esempio i semafori.

Quando non è dovuto alla banale sostituzione di parametri locali con variabili globali definite appositamente, lo stile accumulate and fire può essere un sintomo di difetti a un livello di astrazione più alto. Le misure correttive in questi casi sono:

* definire strutture dati od oggetti globali che raggruppino valori di stato correlati,
* evitare definizioni globali per variabili che sono valide solo in una parte del programma,
* ristrutturare subroutine e metodi complessi che dipendono da molti parametri di ingresso in parti più semplici che dipendono da un numero inferiore di argomenti.
