Parametrizza i metodi rispetto alle variabili globali


10

Ho una domanda molto semplice che mi perseguita da un po 'quando il mio codice inizia a crescere.

I parametri dovrebbero essere sostituiti da variabili globali quando attraversano lunghe rotte di chiamate di funzione nidificate?

Capisco che l'ambiente globale può rendere imprevedibile lo stato di un programma perché molte funzioni possono modificare le variabili condivise, ma lo spazio globale rende le cose così facili.

Mi spiego:

functionA(){
   x = something
   functionB(x)
}
functionB(x){
   functionC(x)
}
functionC(x){
   finallyDoSomethingWithX(x)
}
finallyDoSomethingWithX(x){
  x += 1 //Very dummy example ignoring pass by value, not reference.
}

Sostituito da:

globalX;
functionA(){
   globalX = something
   functionB()
}
...
...
...
finallyDoSomethingWithX(){
   globalX += 1
}

Penso che il secondo modo offra tanta libertà di programmazione perché i parametri possono accumularsi facilmente e possono anche essere molto restrittivi a volte quando il codice deve essere riutilizzato, ma allo stesso tempo sento che la funzione perderà la sua modularità quando è correlata a una variabile nell'ambiente globale, perdendo anche riusabilità quando, ad esempio, voglio operare finallyDoSomethingWithXcon un'altra variabile diversa da quella globalX.

Penso che questo mi stia succedendo perché in realtà non sto usando modelli di progettazione perché sto programmando in Javascript, che per me sembra un linguaggio a script unico per tutti i progetti di medie dimensioni.

Qualche consiglio? modelli? Posso essere più specifico se necessario.


5
In genere, se si passano le variabili molto in profondità, non si è risolto correttamente il problema. Per quanto riguarda le variabili globali che guidano lo stato in altre parti del sistema, evitatelo come la peste. È impossibile gestirlo ad un certo punto e troverai cose che si rompono casualmente perché uno stato è mutato da una funzione che non ti aspettavi a caso.
mgw854,

Evitalo come la peste. Inteso. Potresti approfondire un po 'di più "non hai risolto correttamente il problema". Capisco l'idea generale, ma non riesco a trovare un esempio o qualcosa per capirlo davvero.
AFP_555,

2
Un rimedio comune quando ti ritrovi a passare argomenti in profondità su molti livelli è quello di creare un oggetto metodo : un oggetto di una nuova classe i cui metodi corrispondono alle funzioni che trasmettono i parametri. I parametri possono quindi diventare variabili locali per l'oggetto e i suoi metodi non devono più passare lungo i valori.
Kilian Foth,

@KilianFoth Grazie. Potresti per favore elaborare un po 'di codice in modo che io possa controllare la risposta?
AFP_555,

1
Considera di trattare la struttura del tuo codice JavaScript come faresti in altre lingue (come quelle che usano classi "reali"). Alcuni link utili su questa domanda correlata su SO: stackoverflow.com/questions/927651/…
Ben Cottrell,

Risposte:


7

Non usare variabili globali.

Inoltre, non passare i parametri in catene di funzioni!

È difficile perché non usi un esempio reale. Ma normalmente ci sarà un approccio migliore.

Diciamo che abbiamo una variabile password che dobbiamo usare per chiamare le API che inturn sono usate da varie funzioni di basso livello.

Approccio globale (codice psudo)

var pass;

function multiply(a,b) {
   return apiMultiply(pass,a,b);
}

Approccio di passaggio dei parametri

function multiply(a,b,pass) {
    return apiMultiply(pass,a,b);
}

Approccio agli oggetti

class math {
    var api;
    constructor(pass) {
        api = new api(pass);
    }

    function Multiply(a,b) {
        api.Multiply(a,b); //uses pass from constructor
    }
}

Eccellente. In questo modo pass non si trova nell'ambiente globale e inoltre non è un parametro per le funzioni multiple in quanto può essere preso dagli attributi dell'oggetto. Grazie.
AFP_555,

3

Evita i globi come la peste.

Qualsiasi codice può modificare un globale. Quindi se avessi una catena A (x) -> B (x) -> C (x) -> ... -> Z (x), e memorizzi x in una X globale e ora hai una catena A- > B-> C -> ...-> Z, quindi ad ogni singolo passaggio di quella lunga catena, o in codice completamente indipendente, qualcuno potrebbe cambiare X. E il valore che Z usa potrebbe essere completamente diverso da quello che A iniziato con.

È un incubo se mai vuoi essere sicuro che il tuo codice fa quello che dovrebbe fare, o che fa quello che pensi che faccia.


1
Completamente d'accordo. Se usi i globi per risolvere il tuo problema, ora hai due problemi.
Caleb Mauer,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.