Muitos ifs é má prática?

:?: 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.

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

[quote=Winthorp] :?: 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.[/quote]

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

[quote]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.[/quote]
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.

[quote=Winthorp]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.[/quote]

[quote=Winthorp]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.[/quote]

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á :smiley:

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 :smiley:

[quote=Mark_ameba]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.
[/quote]

Poderia fazer assim:
a)

[code]JButton btn = new JButton(“Executar”);
btn.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
         executar();
}

});[/code]
b)

[code]JButton btn = new JButton(“Executar”);
btn.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
         MinhaClasse.this.controller.executar();
}

});[/code]
c)

[code]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;	

}
[/code]

flws

[quote=fantomas][quote=Mark_ameba]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.
[/quote]

Poderia fazer assim:
a)

[code]JButton btn = new JButton(“Executar”);
btn.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
         executar();
}

});[/code]
b)

[code]JButton btn = new JButton(“Executar”);
btn.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
         MinhaClasse.this.controller.executar();
}

});[/code]
c)

[code]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;	

}
[/code]

flws[/quote]
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);

Esse seria melhor que abaixo?

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 :wink:

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.