Boa tarde!
Não ficou claro se é uma boa prática usar um setter, usar um setter e o construtor, ou apenas o construtor. Como devo avaliar essa necessidade?
Segue o código para exemplificar como seria o setter + o construtor:
- Classe 1
package br.com.alura.designpatternsI.chainOfResponsability;
import br.com.alura.designpatternsI.strategy.*;
public class IsencaoPorOrcamentoMenosDeDuzentos implements IsencaoTributaria {
private IsencaoTributaria outraIsencao;
public IsencaoPorOrcamentoMenosDeDuzentos(IsencaoTributaria outraIsencao) {
this.outraIsencao = outraIsencao;
}
public IsencaoPorOrcamentoMenosDeDuzentos() {
}
@Override
public double isenta(Orcamento orcamento) {
if(orcamento.getValor() < 200) {
return orcamento.getValor() * 0.07;
}
return outraIsencao.isenta(orcamento);
}
@Override
public void setProximo(IsencaoTributaria outraIsencao) {
this.outraIsencao = outraIsencao;
}
}
- Classe 2
package br.com.alura.designpatternsI.chainOfResponsability;
import br.com.alura.designpatternsI.strategy.*;
public class IsencaoPorOrcamentoMenosDeTrezentos implements IsencaoTributaria {
private IsencaoTributaria outraIsencao;
public IsencaoPorOrcamentoMenosDeTrezentos(IsencaoTributaria outraIsencao) {
this.outraIsencao = outraIsencao;
}
public IsencaoPorOrcamentoMenosDeTrezentos() {
}
@Override
public double isenta(Orcamento orcamento) {
if(orcamento.getValor() < 300) {
return orcamento.getValor() * 0.03;
}
return outraIsencao.isenta(orcamento);
}
@Override
public void setProximo(IsencaoTributaria outraIsencao) {
this.outraIsencao = outraIsencao;
}
}
- Interface:
package br.com.alura.designpatternsI.chainOfResponsability;
import br.com.alura.designpatternsI.strategy.*;
public interface IsencaoTributaria {
public double isenta(Orcamento orcamento);
public void setProximo(IsencaoTributaria isencao);
}
- Montador:
package br.com.alura.designpatternsI.chainOfResponsability;
import br.com.alura.designpatternsI.strategy.*;
public class MontadorDeIsencoes {
public double calcula(Orcamento orcamento) {
IsencaoPorOrcamentoMenosDeDuzentos i1 = new IsencaoPorOrcamentoMenosDeDuzentos();
IsencaoPorOrcamentoMenosDeTrezentos i2 = new IsencaoPorOrcamentoMenosDeTrezentos();
SemIsencao i3 = new SemIsencao();
i1.setProximo(i2);
i2.setProximo(i3);
return i1.isenta(orcamento);
}
}
- Classe do final da cadeia:
package br.com.alura.designpatternsI.chainOfResponsability;
import br.com.alura.designpatternsI.strategy.Orcamento;
public class SemIsencao implements IsencaoTributaria {
@Override
public double isenta(Orcamento orcamento) {
return 0;
}
@Override
public void setProximo(IsencaoTributaria isencao) {
}
}
- Teste
package br.com.alura.designpatternsI.chainOfResponsability;
import br.com.alura.designpatternsI.strategy.*;
public class Teste {
public static void main(String[] args) {
ICMS icms = new ICMS();
ISS iss = new ISS();
Orcamento orcamento = new Orcamento(199);
MontadorDeIsencoes Isencoes = new MontadorDeIsencoes();
IsencaoPorOrcamentoMenosDeDuzentos i1 = new IsencaoPorOrcamentoMenosDeDuzentos();
IsencaoPorOrcamentoMenosDeTrezentos i2 = new IsencaoPorOrcamentoMenosDeTrezentos();
SemIsencao i3 = new SemIsencao();
double calcula = Isencoes.calcula(orcamento);
System.out.println(calcula);
}
}
Enfim: o intuito de proteger contra null já no construtor é interessante; mas, nesse caso, o setter parece mais prático. É possível compatibilizar as duas coisas? Qual delas devo utilizar?