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 greatestHeightainda 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 updateStatsmé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; }
}
}