Se você se sentiu obrigado a expandir um forro como
a = F(G1(H1(b1), H2(b2)), G2(c1));
Eu não te culpo. Isso não é apenas difícil de ler, é difícil de depurar.
Por quê?
- É denso
- Alguns depuradores destacam tudo de uma só vez
- É livre de nomes descritivos
Se você expandi-lo com resultados intermediários, obtém
var result_h1 = H1(b1);
var result_h2 = H2(b2);
var result_g1 = G1(result_h1, result_h2);
var result_g2 = G2(c1);
var a = F(result_g1, result_g2);
e ainda é difícil de ler. Por quê? Ele resolve dois dos problemas e introduz um quarto:
É denso
Alguns depuradores destacam tudo de uma só vez
- É livre de nomes descritivos
- Está cheio de nomes não descritivos
Se você expandi-lo com nomes que adicionam significado novo, bom e semântico, melhor ainda! Um bom nome me ajuda a entender.
var temperature = H1(b1);
var humidity = H2(b2);
var precipitation = G1(temperature, humidity);
var dewPoint = G2(c1);
var forecast = F(precipitation, dewPoint);
Agora, pelo menos, isso conta uma história. Isso corrige os problemas e é claramente melhor do que qualquer outra coisa oferecida aqui, mas exige que você crie os nomes.
Se você faz isso com nomes sem sentido como result_this
e result_that
porque simplesmente não consegue pensar em bons nomes, eu realmente prefiro que você nos poupe da confusão de nomes sem sentido e a expanda usando um bom e velho espaço em branco:
int a =
F(
G1(
H1(b1),
H2(b2)
),
G2(c1)
)
;
É tão legível, se não mais, do que aquele com os nomes de resultados sem sentido (não que esses nomes de função sejam tão bons).
É denso
Alguns depuradores destacam tudo de uma só vez
- É livre de nomes descritivos
Está cheio de nomes não descritivos
Quando você não consegue pensar em bons nomes, é tão bom quanto possível.
Por alguma razão, os depuradores adoram novas linhas, então você deve achar que isso não é difícil para depurar:
Se isso não for suficiente, imagine que G2()
foi chamado em mais de um lugar e aconteceu:
Exception in thread "main" java.lang.NullPointerException
at composition.Example.G2(Example.java:34)
at composition.Example.main(Example.java:18)
Eu acho bom que, uma vez que cada G2()
chamada esteja em sua própria linha, esse estilo o leve diretamente à chamada ofensiva em geral.
Portanto, não use os problemas 1 e 2 como uma desculpa para nos manter com o problema 4. Use bons nomes quando puder pensar neles. Evite nomes sem sentido quando não puder.
As Raças da Luminosidade no comentário da Orbit apontam corretamente que essas funções são artificiais e têm nomes próprios mortos. Então, aqui está um exemplo de aplicação desse estilo a algum código natural:
var user = db.t_ST_User.Where(_user => string.Compare(domain,
_user.domainName.Trim(), StringComparison.OrdinalIgnoreCase) == 0)
.Where(_user => string.Compare(samAccountName, _user.samAccountName.Trim(),
StringComparison.OrdinalIgnoreCase) == 0).Where(_user => _user.deleted == false)
.FirstOrDefault();
Eu odeio olhar para esse fluxo de ruído, mesmo quando a quebra de linha não é necessária. Veja como fica sob esse estilo:
var user = db
.t_ST_User
.Where(
_user => string.Compare(
domain,
_user.domainName.Trim(),
StringComparison.OrdinalIgnoreCase
) == 0
)
.Where(
_user => string.Compare(
samAccountName,
_user.samAccountName.Trim(),
StringComparison.OrdinalIgnoreCase
) == 0
)
.Where(_user => _user.deleted == false)
.FirstOrDefault()
;
Como você pode ver, eu descobri que esse estilo funciona bem com o código funcional que está sendo movido para o espaço orientado a objetos. Se você pode criar bons nomes para fazer isso em estilo intermediário, terá mais poder para você. Até então eu estou usando isso. Mas, em qualquer caso, por favor, encontre uma maneira de evitar nomes de resultados sem sentido. Eles fazem meus olhos doerem.