Limpe passagem de parâmetro profunda do código

5

Código tão limpo diz que você deve separar cada tarefa para uma única função (e adicionar um nome correto a essas funções).

Eu gostei da idéia, mas eu enfrentei esse problema até agora: você recebe um parâmetro que você quer usar também na função mais alta, mas você precisa no nível mais baixo também, então você tem que passar o parâmetro para cada função intermediária, o que não é legal.

Aqui está o meu código:

onUpdate = function(currentSeconds){
    updateRoute(currentSeconds);
    updateAlerts(currentSeconds);
};
updateAlerts = function(currentSeconds){
    for(var i = 0; i < alertMarkers.length; ++i)
        oneAlertUpdate(currentSeconds, alertMarkers[i], alertAll[i]);
}
oneAlertUpdate = function(currentSeconds, alertMarker, alert){
        updateAlertMarker(alertMarker, alert[entryIndex]);
        changeMarkerOpacityIfNeeded(alertMarker, currentSeconds);
    }
}
changeMarkerOpacityIfNeeded = function(alertMarker, currentSeconds){
    //set opacity based on currentSeconds
    var opacity = alertMarker.opacityTime < currentSeconds ? 1 : 0.5;
    if(alertMarker.getOpacity() != opacity)
        alertMarker.setOpacity(opacity);
}
  • o parâmetro aqui é currentSeconds ele precisa ser passado, mas é usado apenas no nível mais baixo
  • por favor note que eu não uso currentSeconds diretamente na função mais importante, mas é crucial passar por lá, vou escrever o motivo se você disser que é relevante
por Ferenc Dajka 05.04.2016 / 11:41
fonte

2 respostas

2

Uma opção poderia ser criar uma "classe" (ou o equivalente do JavaScript neste caso), que se comporta como um functionoid / functor, e armazena currentSeconds , então chama para essa 'classe' [sic] de um proxy função para garantir que você ainda esteja chamando apenas onUpdate do código de chamada:

var Alerter = (function () {
    function Alerter(currentSeconds) {
        this.currentSeconds = currentSeconds;
    }

    Alerter.prototype.onUpdate = function () {
        this.updateRoute();
        this.updateAlerts();
    };

    Alerter.prototype.updateAlerts = function () {
        for (var i = 0; i < alertMarkers.length; ++i)
            this.oneAlertUpdate(alertMarkers[i], alertAll[i]);
    };

    Alerter.prototype.oneAlertUpdate = function (alertMarker, alert) {
        this.updateAlertMarker(alertMarker, alert[entryIndex]);
        this.changeMarkerOpacityIfNeeded(alertMarker);
    };

    Alerter.prototype.changeMarkerOpacityIfNeeded = function (alertMarker) {
        //set opacity based on currentSeconds
        var opacity = alertMarker.opacityTime < this.currentSeconds ? 1 : 0.5;
        if (alertMarker.getOpacity() != opacity)
            alertMarker.setOpacity(opacity);
    };

    return Alerter;
}());


function onUpdate(currentSeconds) {
    new Alerter(currentSeconds).onUpdate();
}
A principal desvantagem disso é a complexidade adicional no código, que apenas nega a maior parte do benefício em evitar passar repetidamente a mesma variável em primeiro lugar.

No entanto, evita esse bit de duplicação, e o código de chamada não deve notar nenhuma diferença, pelo menos:

var currentSeconds = 5;
onUpdate(currentSeconds);

Mas, no geral, não tenho certeza se essa abordagem é realmente "mais limpa"; as soluções mais simples são geralmente as melhores.

    
por 05.04.2016 / 12:17
fonte
0

Funções como oneAlertUpdate e changeMarkerOpacityIfNeeded precisam estar visíveis fora de updateAlerts ? Caso contrário, pode ser fácil evitar a necessidade de "passar" os valores da cadeia de chamadas.

onUpdate = function(currentSeconds){
    updateRoute(currentSeconds);
    updateAlerts(currentSeconds);
};

updateAlerts = function(currentSeconds){
    oneAlertUpdate = function(alertMarker, alert){
            updateAlertMarker(alertMarker, alert[entryIndex]);
            changeMarkerOpacityIfNeeded(alertMarker);
        }
    }
    changeMarkerOpacityIfNeeded = function(alertMarker){
        //set opacity based on currentSeconds
        var opacity = alertMarker.opacityTime < currentSeconds ? 1 : 0.5;
        if(alertMarker.getOpacity() != opacity)
            alertMarker.setOpacity(opacity);
    }

    for(var i = 0; i < alertMarkers.length; ++i)
        oneAlertUpdate(alertMarkers[i], alertAll[i]);
}
    
por 03.11.2016 / 06:47
fonte