:?: Pessoal, estou trabalhando em um código onde eu acrescento um if ou um for sempre que acho necessário para conseguir o resultado que estou procurando.
A pergunta é: ter muitos if´s no código é uma má prática de programação? Mesmo que se obtenha o resultado esperado?
Sempre ouvi falar em gambiarras em códigos, mas não saberia dizer o que é uma gambiarra num código.
Se os mais tarimbados em programação puderem dar uma opinião, fico agradecido.
abs.
Muitos ifs é má prática?
25 Respostas
as vezes é possível usar outras estruturas como swith/case, depende de cada caso.
bom…eu não sou alguém bastante “tarimbado” mais acredito ter uma opinião a se considerar…claro q não a verdade absoluta…
isso é uma coisa q depende da facilidade de leitura do código e do desempenho… é necessario um pouco de bom senso… dai vai depender mais das espressões que são colocadas nos ifs do que na quantidade deles…
claro que muitos atrapalham um pouco, mais de uma forma geral acho que depende mais do quanto é facil ler esse código, da forma que vc identa eses ifs…etc
:?: Pessoal, estou trabalhando em um código onde eu acrescento um if ou um for sempre que acho necessário para conseguir o resultado que estou procurando.
A pergunta é: ter muitos if´s no código é uma má prática de programação? Mesmo que se obtenha o resultado esperado?
Sempre ouvi falar em gambiarras em códigos, mas não saberia dizer o que é uma gambiarra num código.
Se os mais tarimbados em programação puderem dar uma opinião, fico agradecido.
abs.
A resposta é, como sempre, “depende”. É bom ver exemplos de códigos bem-escritos em vez de olhar só os que você escreveu. Baixe os fontes de projetos (open-source ou não) e dê uma boa lida.
Na minha opinião muitos ifs são sim má pratica, porque geralmente quando se tem muitos ifs é porque a OO não esta muito boa…
Ja cansei de ver classes assim…
public void DaoCliente{
public void faz(String oque, Cliente cliente)
{
if (oque=="cadastrar")
// cadastrar
if (oque=="deleta")
// deleta
if (oque=="atualiza")
// atualiza
}
}
Mas é claro tem situações que não tem como fugir…kkk
flw!!!
Com relação a usar switch/case acho que não se aplica nos casos que estou mexendo e não consigo pensar em outras estruturas para os casos.
Eu procuro deixar bem identado e até colocar uns comentários sobre o porquê do if.
Mas legal, obrigado pelas dicas.
Cada caso é um caso [haha].
Acredito que o abuso de if seja uma má prática. Procure utilizar switch-case ou polimorfismo quando possível.
Até.
Métodos entupidos de if’s, fors e whiles normalmente deveriam ser quebrados em métodos menores. Senão vira aquele espaguete só. Sempre que for esbarrar em um if, switch, while ou do-while, principalmente se estes tiverem mais do que 3 ou 4 linhas, pense bem se não seria melhor separá-lo em um método a parte.
Quem nunca viu aquele método com 1500 linhas tendo centenas de if/else, switchs e fors aninhados caoticamente e ficou com vontade de despedaçar o autor de uma forma bem sanguinária?
AFFF rsrs
Cada caso é um caso [haha].
Acredito que o abuso de if seja uma má prática. Procure utilizar switch-case ou polimorfismo quando possível.
Em várias situações no código em que estou trabalhando, eu preciso verificar o resultado da execução de um método para decidir sobre a execução de outro trecho de código. Estou verificando mas não consigo pensar em nada que seja melhor que os if´s e for´s.
vlw.
Como o pessoal ai ja comentou…
Muitos if’s podem ser mau uso da OO, eu mesmo ja encontrei diversas situações em que o polimorfismo e sobrescrita dimuiram consideravelmente o “ninho de passarinho”…
Fora que a leitura, compreensão e manutenção do código ficam muito bons…
Concordo que existem situações complicadas de resolver sem eles… mas se tiver tempo, repense no código que está escrevendo e veja se não tem outra forma de fazer… e se mesmo assim for preciso abusar dos if’s, não esqueça de documentar muito bem cada um deles…
Fui !!!
Obrigado a todos pelas dicas.
Certas coisas que pedem um monte de ifs, fors e whiles à primeira vista, deveriam é ser resolvidos com máquinas de estados, com “subclassing” ou com divisão em diversos métodos.
Depende muito do que deve ser feito.
IFs / Switch cases são indicadores de uso adequado ou inadequado da OO sim.
A quantidade tem que TENDER a ZERO; ou seja, na maioria das vezes vc, mesmo aplicando tecnicas de OO, não irá fazer com que eles desapareçam mas eles irão ficar BEM simples de entender, o que já é muito bom.
Não se consegue isso de forma rápida, porém não é muito difícil, tem que QUERER atingir esta condição; estudar os padrões (design patterns) e conhecer bem as regras de negócio que estão envolvidas são bastante indicados.
O Mr. Martin Fowler publicou um livro sobre refactoring muito bom se possível consigam este livro, é claro que outros são bem vindos. Livros sobre boas práticas de programação tem várias dicas de como melhorar as estruturas condicionais também, vale a pena conferir.
flws
Agora pensando nisso o que é melhor em tratamento de eventos em Swing?
Uma anonymous class para cada evento de botão ou então um Listener com if/else if/…/else if/else para jogar a ação para algum método?
De certo modo também é difiçil ler muitas anonymous class.
Com relação a usar switch/case acho que não se aplica nos casos que estou mexendo e não consigo pensar em outras estruturas para os casos.
Eu procuro deixar bem identado e até colocar uns comentários sobre o porquê do if.
Mas legal, obrigado pelas dicas.
Em várias situações no código em que estou trabalhando, eu preciso verificar o resultado da execução de um método para decidir sobre a execução de outro trecho de código. Estou verificando mas não consigo pensar em nada que seja melhor que os if´s e for´s.
vlw.
bom… comentario de mais, já demostra que o codigo não ta muito legal, isso quando o comentario é dentro do código, não to falando de javadoc … e se vc ta tendo que em todo canto checar o que vc ta fazendo, então mostra que todo mundo ta se responsabilizando por testar seu código… normalmente o OO não ta legal nesses casos.
o ideal é vc procurar ver quem é responsável por oque, e deichar para os responsáveis para fazer seus testes…
…
vou te dar 1 exemplo, eu tenho um repositorio no projeto atual que estou trabalhando.
Eu defini que o repositorio não é responsável pelas regras de negocio, portanto ele não checa nada, sobre se pode ou não adcionar algo ao banco de dados, que fica por traz do repositorio…
Se eu mandar um objeto pra ser salvo no repositorio, ele não vai checar o objeto, ele simplismente vai encaminhar pra tabela certa, dentro do mysql, e vai tentar dar um INSERT/UPDATE no objeto, c não conseguir faze-lo, ele devolve o erro pra cima, o repositorio é ignorante total sobre as regras de negocio, ele simplismente pega, joga pro banco, salva, e devolve uma resposta do que ocorreu…
Eu tenho um objeto de negocio bem simples, por exemplo, que é um catalogo de cidades, quando eu mando uma cidade pra ele, e solicite que ele salve a cidade, ele verifica se existem cidades com o mesmo nome no mesmo estado, verifica se eu tenho permisão para salvar, e depois encaminha para o repositorio, ele que avisa que ja existe, e não deixa salvar, ele é reponsável por tratar esse evento… tente verificar quem é responsável pelo o que, no seu negocio, que talvez vc consiga liberar alguns IFs…
…
outra coisa é quebrar o código, ajuda bastante.
Com certeza algum polimorfismo ou pattern pode ser utilizado para eliminar alguns. Um bom exemplo é o Strategy.
normalmente quando a gente nota que alguma coisa pode estar erra, é porque está 
um tempo atrás o vini deu uma dica exatamente sobre isso nesse post:
http://www.guj.com.br/posts/list/55885.java
isso tem me ajudado bastante, principalmente a dica do livro 
Agora pensando nisso o que é melhor em tratamento de eventos em Swing? Uma anonymous class para cada evento de botão ou então um Listener com if/else if/.../else if/else para jogar a ação para algum método?Poderia fazer assim: a)De certo modo também é difiçil ler muitas anonymous class.
JButton btn = new JButton("Executar");
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
executar();
}
});
JButton btn = new JButton("Executar");
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
MinhaClasse.this.controller.executar();
}
});
JButton btn = new JButton("Executar");
btn.addActionListener(this.createExecutarAction());
...
private ActionListener createExecutarAction() {
ActionListener action = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//LOGICA A SER EXECUTADA
};
return action;
}
flws
Agora pensando nisso o que é melhor em tratamento de eventos em Swing? Uma anonymous class para cada evento de botão ou então um Listener com if/else if/.../else if/else para jogar a ação para algum método?Poderia fazer assim: a)De certo modo também é difiçil ler muitas anonymous class.
b)JButton btn = new JButton("Executar"); btn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { executar(); } });c)JButton btn = new JButton("Executar"); btn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { MinhaClasse.this.controller.executar(); } });JButton btn = new JButton("Executar"); btn.addActionListener(this.createExecutarAction()); ... private ActionListener createExecutarAction() { ActionListener action = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { //LOGICA A SER EXECUTADA }; return action; }flws
Não é essa minha duvida estou falandi mais ou menos isso..
final JButton add = new JButton("Add");
final JButton del = new JButton("Delete");
final JButton srch = new JButton("Search");
final JButton close = new JButton("Close");
ActionListener listener = new ActionListener(){
@Override
public void actionPerformed(ActionEvent event){
Object source = event.getSource();
if(source == add)
doAdd(event);
else if(source == del)
doDel(event);
else if(source == srch)
doSearch(event);
else if(source == close)
doClose();
}
}
add.addActionListener(listener);
del.addActionListener(listener);
srch.addActionListener(listener);
close.addActionListener(listener);
final JButton add = new JButton("Add");
final JButton del = new JButton("Delete");
final JButton srch = new JButton("Search");
final JButton close = new JButton("Close");
ActionListener listener =
add.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent event){
doAdd(event);
}
});
del.addActionListener(lnew ActionListener(){
@Override
public void actionPerformed(ActionEvent event){
doDel(event);
}
});
srch.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent event){
doSearch(event);
}
});
close.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent event){
doClose();
}
});
Respondendo a sua pergunta:
O que o evento ‘add’ tem que saber sobre o evento ‘del’?
Sem falar que, se o método a ser chamado é sempre ‘doNomeDaAção’ vc poderia invocar via reflection, ai vc poderia ter um ‘listener’ genérico, que pode ser adicionado a qq botão 
Outro argumnto sobre muitos ifs: existe teste unitário? Se existe, qual a cobertura?
Bastaria rodar os testes junto do EMMA para ver quais ifs não estão sendo exercitados. Se for muito dificil exercitar todos os caminhos via testes, mocks e injeção de testabilidade, provavelmente tem algo de estranho.
Humm… entendi.
Eu prefiro a segunda opção, apesar de ela parecer mais “congestionada”, pelo fato de ela ser mais orientada a objetos (sem ifs). A primeira opção é bastante linear.
É claro que, como já disseram, o que vale é o bom senso; ou seja, quando a coisa é muito simples tanto faz uma solução ou outra. Os mais aficcionados em OO irão certamente optar pela sua segunda opção, os iniciantes (principalmente os que vem de linguagens procedurais) optam pela sua primeira opção.
A segunda opção vai fazer com que vc pense na OO (se querer isso é lógico) para resolver os problemas caso o código aumente de tamanho a primeira opção vai lhe deixar cada vez mais longe da OO quando o código aumentar, porque ele é linear, sem falar no risco de alta dependencia na lógica do código.
flws
tem casos que vc podera remover ifs usando um Map de ações… usei isto uma vez… imagine a seguinte situação… vc tem codigos de A a Z que são dados de entrada dependendo cada codigo vc ira executar uma determinada ação… para isto vc pode usar um mapa de ações e não necessariamente um switch gigante muito menos ifs… pode parecer meio gambiarrento um mapa de ações porem e um uso bastante proveitoso de polimorfismo… mas depende de cada caso… tera casos que polimorfismo podera eliminar centenas de ifs e switchs e casos que vc realmente precisara deles… por exemplo em uma grande maquina de estados não vejo muita saida para com ifs…
Agora pensando nisso o que é melhor em tratamento de eventos em Swing?
Uma anonymous class para cada evento de botão ou então um Listener com if/else if/…/else if/else para jogar a ação para algum método?De certo modo também é difiçil ler muitas anonymous class.
Uma anonymous class para cada evento cujo método actionPerformed (ou os métodos correspondentes caso seja outro tipo de listener) simplesmente chame um método da classe externa.
Dá mais linhas de código, mas fica muito mais simples, mais fácil de entender e mais fácil de evoluir.
bom… comentario de mais, já demostra que o codigo não ta muito legal, isso quando o comentario é dentro do código, não to falando de javadoc … e se vc ta tendo que em todo canto checar o que vc ta fazendo, então mostra que todo mundo ta se responsabilizando por testar seu código… normalmente o OO não ta legal nesses casos.o ideal é vc procurar ver quem é responsável por oque, e deichar para os responsáveis para fazer seus testes…
Na verdade, o código que estou mexendo já foi criado por alguém que nem está mais na empresa.
Eu tenho que customizá-lo para novas funcionalidades sem danificar o que já está funcionando.
Obrigado mais uma vez, estou analizando todas as sugestões e quando aplicáveis, com certeza irei usá-las.
abs.
Eu uso um Map<JButon, Method> mesmo… só queria saber ^^.
Bem pessoal,
Na época que eu estava estudando pra tirar uma certificação da Borland, meu instrutor dizia que é possível conhecer o nível do programador pela quantidade de IF´s que ele utiliza…
Concordo com o pessoal quando a resposta é “depende”…rs
Na minha opnião, a quantidade de IF´s pode ser resultado de uma visão limitada de lógica ou realmente não tem como fazer de outra forma.
Sugestão :
Entregue a mesma situação lógica para 2 programadores…se um fizer com 10 If´s e o outro com 5 If´s… e ambos chegaram ao mesmo resultado e o mesmo nível de tratamento da informação…pode acreditar, isso é uma “má prática”.
Abraços,
Francisco Rosemberg