Parametrizar métodos x variáveis ​​globais

10

Eu tenho uma pergunta muito simples que me assombra há um tempo quando meu código começa a crescer.

Os parâmetros devem ser substituídos por variáveis ​​globais quando passam por longas rotas de chamadas de funções aninhadas?

Entendo que o ambiente global pode tornar o estado de um programa imprevisível porque muitas funções podem modificar variáveis ​​compartilhadas, mas ainda assim, o espaço global facilita as coisas.

Deixe-me me explicar:

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.
}

Substituído por:

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

Eu sinto que a segunda maneira dá tanta liberdade para programar porque os parâmetros podem se acumular facilmente e também podem ser muito restritivos às vezes quando o código deve ser reutilizado, mas ao mesmo tempo, sinto que a função perderá sua modularidade quando estiver relacionada a uma variável no ambiente global, perdendo também a capacidade de reutilização quando, por exemplo, quero operar finallyDoSomethingWithXcom outra variável diferente tha globalX.

Acho que isso está acontecendo comigo porque, na verdade, não estou usando padrões de design porque estou programando em Javascript, o que para mim parece uma linguagem de um script que lida com tudo para projetos médios.

Algum conselho? padrões? Eu posso ser mais específico, se necessário.

AFP_555
fonte
5
Normalmente, se você está passando variáveis ​​muito profundamente, não resolveu o problema corretamente. Quanto às variáveis ​​globais que conduzem o estado em outras partes do sistema, evite-o como uma praga. É impossível gerenciar em um determinado momento, e você encontrará coisas quebrando aleatoriamente porque algum estado é modificado por uma função que você não esperava aleatoriamente.
mgw854
Evite como uma praga. Entendido. Você poderia elaborar um pouco mais sobre "você não quebrou o problema corretamente". Eu entendo a idéia geral, mas não consigo criar um exemplo ou algo para entendê-la de verdade.
AFP_555 14/04
2
Um remédio comum quando você se depara com argumentos em muitas camadas é criar um objeto de método : um objeto de uma nova classe cujos métodos correspondem às funções que transmitem os parâmetros. Os parâmetros podem se tornar variáveis ​​locais para o objeto e seus métodos não precisam mais repassar os valores.
Kilian Foth
@KilianFoth Thanks. Você poderia elaborar algum código para que eu possa verificar a resposta?
AFP_555
1
Considere tratar a estrutura do seu código JavaScript como faria em outros idiomas (como aqueles que usam classes "reais"). Alguns links úteis sobre esta questão relacionada no SO: stackoverflow.com/questions/927651/…
Ben Cottrell

Respostas:

7

Não use variáveis ​​globais.

Além disso, não passe parâmetros para cadeias de funções!

É difícil porque você não usa um exemplo real. Mas normalmente haverá uma abordagem melhor.

Digamos que temos uma variável de senha que precisamos usar para chamar apis que inturn são usadas por várias funções de baixo nível.

Abordagem global (código psudo)

var pass;

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

Abordagem de passagem de parâmetros

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

Abordagem de objetos

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

    function Multiply(a,b) {
        api.Multiply(a,b); //uses pass from constructor
    }
}
Ewan
fonte
Excelente. Dessa forma, o passe não está no ambiente global e também não é um parâmetro para funções múltiplas, pois pode ser retirado dos atributos do objeto. Obrigado.
AFP_555
3

Evite globais como a praga.

Qualquer código pode modificar um global. Portanto, se você tivesse uma cadeia A (x) -> B (x) -> C (x) -> ... -> Z (x), e você armazenasse x em um X global e agora você tiver uma cadeia A- > B-> C -> ...-> Z, então, a cada passo dessa cadeia longa, ou em código completamente independente, alguém poderia mudar X. E o valor que Z usa pode ser completamente diferente daquele que A começou com.

É um pesadelo se você quiser ter certeza de que seu código faz o que deve fazer ou que faz o que você pensa que faz.

gnasher729
fonte
1
Concordo plenamente. Se você usa globais para resolver seu problema, agora você tem dois problemas.
Caleb Mauer