O problema que você está descrevendo é muito comum: você tem um loop que produz determinados dados e deseja agregar várias "estatísticas" dos dados gerais. A implementação direta é, como você disse, ter várias variáveis locais que são atualizadas a cada iteração:
int greatestHeight, greatestSpeed, leastWeight;
Runner tallestRunner, fastestRunner, lightestRunner;
for(...){
runner = ... // the runner comes from somewhere, not necessarily a list
if(runner.height > greatestHeight) { greatestHeight = runner.height; tallestRunner = runner; }
if(runner.speed > ...
}
Isso não tem uma boa separação de preocupações, porque você tem a lógica de agregação alinhada com a produção dos dados. Extrair a lógica de agregação em um método (como proposto nesta resposta ) é uma melhoria, mas o isolamento ainda não é bom: os resultados intermediários e (se necessário) variáveis auxiliares como greatestHeight
ainda precisam ser variáveis locais.
Portanto, a IMHO é a única boa solução para extrair a lógica de agregação e as atribuições em um método.
Como isso pode ser feito? Refatorando primeiro as variáveis locais em campos. Em seguida, você pode, por exemplo, extrair um método updateStats(runner)
que atualize os campos tallestRunner
/ fastestRunner
/ ... e os campos greatestHeight
/ greatestSpeed
/ ... correspondentes .
Mas isso não piora o isolamento? Sim, a princípio, mas isso pode ser corrigido por uma refatoração de classe de extração : Mova os campos estatísticos e o updateStats
método para uma nova classe (por exemplo, aninhada). Portanto, no final, você terá a seguinte solução legível e de passagem única:
RunnerStats stats = new RunnerStats();
for(...){
runner = ...
stats.updateStats(runner);
}
... = stats.tallestRunner;
}
static class RunnerStats{
int greatestHeight, greatestSpeed, leastWeight = Integer.MAX_VALUE;
Runner tallestRunner, fastestRunner, lightestRunner;
void updateStats(Runner runner){
updateTallest(runner);
update...
}
void updateTallest(Runner runner){
if(runner.height > greatestHeight) { greatestHeight = runner.height; tallestRunner = runner; }
}
}