Uma das disciplinas ministradas em todos os cursos na área de Computação, é a disciplina de Programação Orientado a Objetos. Muitos alunos ficam se perguntando: “Como fixar esse novo paradigma?”. Há várias maneiras de aprender, creio que tenha diversas formas, porém, existem maneiras equivocadas de aprender.
Uma das práticas mais contraditórias que aprendemos logo de início é a geração indiscriminada e equivocada de getters e setters. Os exemplos básicos de centenas de materiais Java estão recheados com getters e setters da pior espécie, aqueles que não fazem sentido algum.
Observe a classe Livros:
public class Livros { private String nome; private String descricao; private double valor; private String isbn; private Autor autor; private double porcentagem; public Livros(Autor autor) { this.autor = autor; this.isbn = "000-00-00000-00-0"; } public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; } public String getDescricao() { return descricao; } public void setDescricao(String descricao) { this.descricao = descricao; } public double getValor() { return valor; } public void setValor(double valor) { this.valor = valor; } public String getIsbn() { return isbn; } public void setIsbn(String isbn) { this.isbn = isbn; } public Autor getAutor() { return autor; } public void setAutor(Autor autor) { this.autor = autor; } public double getPorcentagem(){ return porcentagem; } public void setPorcentagem(){ this.porcentagem = porcentagem; }
Geralmente, os tutoriais explicam que o modificador de acesso “private” é o adequado para o encapsulamento e que devemos usar getters e setters para acessá-la. Para que esse setDescricao? Você vai chegar a usar todos esses métodos? Isso só está quebrando o seu encapsulamento!
Não crie um getter ou setter sem sentir uma grande necessidade por ele. E isso vale para qualquer método, mas particularmente os getters e setters, pois muitos deles nunca serão sequer invocados, e grande parte do restante poderia ser substituído por métodos de regras de negócios.
public class Livros { private String nome; private String descricao; private double valor; private String isbn; private Autor autor; public Livros(Autor autor) { this.autor = autor; this.isbn = "000-00-00000-00-0"; } public boolean aplicaDesconto(double porcentagem) { if (porcentagem > 0.3) { return false; } this.valor -= this.valor * porcentagem; return true; } boolean obterAutor(){ return this.autor != null; } }
Testando a classe Livros rapidamente você perceberia que alguns dos getters e setters anteriores não têm uso algum, e logo sentiria falta de alguns métodos mais voltados a lógica das regras de negócio, como o aplicaDesconto.
Existem outras más práticas, como a utilização de ids para relacionar os objetos, arrays não encapsuladas como estruturas, milhares de métodos estáticos, entre outros. Todas essas práticas são muito comuns quando estamos iniciando o “desapego ao paradigma procedural” e sem dúvida a maioria dos profissionais já foram praticantes disso.
Você só vai utilizar bem o paradigma da orientação a objetos depois de programar muito, mas nada melhor que começar já com uma boa prática. Pense nisso ! 😉
14 Comentários
TOTALMENTE de acordo.
Quando estudei a cadeira no curso não achei lógica nenhuma em estar a definir tantos “getters” e “setters” e sentia a necessidade de métodos que faziam operações realmente necessárias e que pudessem simplificar o programa.
Ainda por cima, sou do tempo do MS-DOS, da programação “na unha”.
Abraço.
Está claro no texto que o autor realmente não sabe OO. Acredito que falta maturidade para poder falar sobre esse tema complicado.
Concordo com o que o Pedro falou. Recomendo estudar OO. Leia o livro do Craig.
Utilização de IDS relaciinando objetos?! Da um exemplo disso por favor
Pessoal,bom dia.
Quero deixar claro que não culpo exatamente o getter e setter, mas sim sua geração automática ou quase automática é um grande problema. Eles têm sim uma necessidade muitas vezes, e faz todo sentido usa-los quando sentir a necessidade disso.
Prova disso é que hoje em dia a Sun nao recomenda sua criação automatica (a nao ser necessidades particulares de frameworks, que também tem diminuido).
Sem duvida é importante ter um getter ou setter em vez de um campo publico, mas se nao há a necessidade deles, isso é, nao há codigo que os invoque por enquanto ou não se encaixa um método de negócio, nao tem muito motivo para criar esses métodos.
Concordo em partes Andréia.
Você comentou que “existem maneiras equivocadas de aprender”. Isso concordo.
Usar getters and setters inúteis é prejudicial como qualquer outra implementação inutilizada.
Agora, falando novamente em “maneira equivocada”, se sua classe “Livros” representar realmente o que parece, eu não colocaria regras de negócio na tua classe, já que, teoricamente, ela deve apenas “modelar” o que é um “Livro”.
Só para exemplificar, a classe “Livros” nunca aplicaria desconto “aplicaDesconto();”
Abraço.
Bom, vamos lá: O uso excessivo de getters e setters é realmente um tema polêmico, porém a solução não pode ser simplesmente removê-los. Uma boa prática que programadores novos podem adotar é aplicar o princípio da imutabilidade, que consiste no atributo não poder ser alterado após a criação da estância.
É possível realizar isso da seguinte maneira:
* Deixe todos os atributos como final
* Crie um construtor(Ou aplique o design pattern criacional ‘Builder’) para receber todos os atributos.
* Caso um atributo seja mutável (StringBuilder, List, etc…), retorne uma cópia, e não sua referência real.
Espero ter contribuído de alguma maneira.
Saudações
Faltou um passo:
* Remova os setters 🙂
Primeiramente parabéns pelo artigo, pela coragem, disponibilidade e pelo ativismo na propagação de boas práticas.
Concordo com a ideia principal a respeito do uso indiscriminado de getters e setters, porém sugiro de maneira construtiva avaliar melhor o título dos próximos artigos (por favor continue a publicar), pois na minha humilde opinião houve um tom de “superioridade” em uma área onde todos somos meros mortais e necessitamos de apoio um dos outros, ou seja, na área de desenvolvimento acredito que a união faça a força (GitHub é a prova).
Digo isso, pois acredito também que um “Livro” não “aplica descontos”, também tenho fé que um dos principais pilares da OO trata exatamente desta questão: a abstração do mundo real.
Quanto a abstração, isso sempre irá variar de cabeça para cabeça, porém existe também o conceito “SRP” (Single Responsibility Principle / Princípio de Responsabilidade Única) que prega que uma classe deve ter uma única responsabilidade, portanto acredito que o exemplo poderia ser outro.
E assim vamos aprendendo, também posso ter falado alguma bobagem, fiquem a vontade para corrigir e complementar.
Obrigado pela atenção.
A ideia do artigo é realmente interessante e muito polêmica, pois quando se fala em boas práticas é comum que as pessoas tenham maneiras diferentes de utiliza-las, e também muitas coisas em comum. Mas vejo sua opinião de uma forma confusa(sem ofensas), pois sou iniciante da área e não vejo uma situação em que eu simplesmente vou criar métodos mesmo sendo getters e setters que não vou utiliza-los. Acredito também que é visível quando um método é desnecessário em uma classe e se foi utilizado de forma excessiva é facilmente percebido e corrigido evitando a sua concretização no projeto. Ainda sou iniciante da área, espero que tenham compreendido meu ponto de vista.
Concordo contigo quando se tratar de classes de negócios. Nestes casos você foi perfeita na sua colocação e somente getters e setters necessários devem ser criados.
Mas quando se tratar das classes de dados (principalmente inserir e alterar), não tem muito o que fugir… As gerações automáticas existem por conta desses casos. Sim, é péssimo gerar código automático e eu também prefiro criar tudo na unha para deixar o código mais limpo e legível.
Acredito que a assinatura do programador ainda conta muito.
Bom artigo.
Pessoal,obrigada pelo feedback.
Sei que tenho muito o que aprender,estou na graduação ainda.Sem dúvida,os feedbacks de vocês me ajudaram muito.
Boa tarde,
Costumo ler muitos artigos na internet e tinha certeza que já tinha lido algo muito parecido com este post, portanto fui pesquisar e então me recordei onde havia visto isso, foi em uma postagem no blog da Caelum, percebi que de fato o texto é MUITO parecido, nem vou dizer que determinadas partes são realmente idênticas. Portanto acredito, que seria interessante ter citado a fonte que embasou este trabalho, que em parte é um resumo do mesmo texto, com outro exemplo.
Para quem quiser, então segue o complemento:
http://blog.caelum.com.br/nao-aprender-oo-getters-e-setters/
Autor:
https://www.caelum.com.br/instrutores/paulo-silveira/
Olá, Bruno!
Aqui é o Jackson, responsável técnico do PTI.
Agradeço muito pela observação e me comprometo aprofundar mais as avaliações de cópias no momento das revisões de textos.
Realmente o conteúdo é parecido demais e não poderia ter sido publicado desta forma.
Enfim, peço desculpas pela falha, tanto para os leitores quanto para o autor original do texto.