Buscar

Encapsulamento no Java

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 8 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 8 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Blog
Java
Rails
Agile
Web Design
Arquitetura
Inovação
Revisitando a Orientação a Objetos: encapsulamento no Java
Postado em 14. jun, 2012 por Mauricio Aniche em Arquitetura, Java
 Tweet 40
Façamos uma aposta. Tenho certeza que você, ao ver a classe abaixo, consegue perceber um problema nela:
Sim. Os atributos estão todos públicos! Isso vai exatamente contra uma das nossas primeiras lições quando aprendemos Java: atributos devem ser
privados e precisamos de getters e setters para acessá-los. Vamos então fazer essa mudança no código.
Agora está melhor, certo? Ainda não. Deixamos escapar na verdade o grande princípio que está por trás da ideia de colocar atributos como privados.
Do jeito que a classe Pedido está nesse momento, podemos fazer coisas como:
Mas aonde está o problema? Imagine outras 10 classes que fazem a mesma coisa: de alguma forma, elas manipulam o valor total do pedido.
Agora imagine que a regra de negócio do pedido mude: todo item comprado ganha desconto de 5% se o valor dele for superior a 1000 reais.
Implementar essa mudança não será tarefa fácil. Precisaríamos fazê-la em diferentes classes do sistema.
Buscar Caelum | Newsletter | Apostilas |
Compartilhar
class Pedido {
 public String comprador;
 public double valorTotal;
 // outros atributos
}
class Pedido {
 private String comprador;
 private double valorTotal;
 // outros atributos
 
 public String getComprador() { return comprador; }
 public void setComprador(String comprador) { this.comprador = comprador; }
 
 public double getValorTotal() { return valorTotal; }
 public void setValorTotal(double valorTotal) { this.valorTotal = ValorTotal; }
 
 // outros getters e setters
}
Pedido p = new Pedido();
// muda valor do pedido para 200 reais!
p.setValorTotal(p.getValorTotal() + 200.0);
Revisitando a Orientação a Objetos: encapsulamento no Java | blog.cae... http://blog.caelum.com.br/revisitando-a-orientacao-a-objetos-encapsul...
1 de 8 27/2/2013 07:17
Quanto tempo demoraremos para mudar o sistema? Não sabemos exatamente aonde devemos fazer as mudanças já que elas estão espalhadas pelo
código. Esse, aliás, é um dos grandes problemas de códigos legados: uma simples mudança precisa ser feita em tantas classes e, na prática, sempre
esquecemos algum ponto, e nosso sistema frequentemente quebra.
A classe Pedido não foi bem desenhada. Demos acesso direto ao atributo valorTotal, um atributo importante da classe. Veja que o modificador
private nesse caso não adiantou de nada, já que demos também um setter para ele. Vamos tentar diminuir o acesso ao atributo, criando métodos mais
claros para a operação de depósito:
Agora, para adicionarmos um item no Pedido, faremos uso desse novo comportamento:
Mas qual a diferença entre os dois códigos abaixo?
Veja que na primeira linha de código, sabemos exatamente COMO funciona a adição de um novo ítem no pedido: devemos pegar o valor total e
somar o valor novo com desconto de 5% se ele for maior que 1000. Já na segunda linha de código, não sabemos como esse processo funciona.
Quando sabemos O QUÊ um método faz (igual ao método adiciona, sabemos que ele adiciona um ítem no pedido, por causa do nome dele), mas não
sabemos exatamente como ele faz, dizemos que esse comportamento está encapsulado!
A partir do momento que as outras classes não sabem como a classe principal faz o seu trabalho, significa que as mudanças ocorrerão apenas em um
lugar! Afinal, elas estão escondidas (encapsuladas)!
class Pedido {
 private String comprador;
 private double valorTotal;
 // outros atributos
 
 public String getComprador() { return comprador; }
 public double getValorTotal() { return valorTotal; }
 
 public void adiciona(Item item) {
 if(item.getValor() < 1000) this.valorTotal += item.getValor();
 else this.valorTotal += item.getValor() * 0.95;
 }
}
Pedido p = new Pedido();
p.adiciona(new Item("Chuveiro Elétrico", 500.0));
Item item = new Item("Super Geladeira", 1500.0);
 
// antiga
if (item.getValor() > 1000) {
 c1.setValorTotal(c1.getValorTotal() + item.getValor() * 0.95);
}
else {
 c1.setValorTotal(c1.getValorTotal() + item.getValor());
}
 
// nova
c1.adiciona(item);
Revisitando a Orientação a Objetos: encapsulamento no Java | blog.cae... http://blog.caelum.com.br/revisitando-a-orientacao-a-objetos-encapsul...
2 de 8 27/2/2013 07:17
Mauricio Aniche (Google+)
Ou seja, para implementar a regra de negócios nova, bastaria mexermos em um único lugar:
No fim, a real utilidade do private é esconder acesso de atributos que precisam ser acessados de maneira mais inteligente. Mas veja que de nada
adianta colocar todos os atributos como private e criar getters e setters para todos eles. Deixamos o encapsulamento “vazar” do mesmo jeito.
Esconda os atributos, mas pense em comportamentos inteligentes para acessá-los. Uma ótima maneira para saber se o comportamento está
encapsulado é olhar para o código que faz uso dele! Se conseguirmos dizer o que o método faz, mas sem dizer como ele faz, então podemos afirmar
que o comportamento está encapsulado!
Muitas vezes deixamos esses princípios passarem. Se quiser revisitar essas e outras boas práticas de Orientação a Objetos junto com os instrutores da
Caelum, há mais posts por aqui, como um específico sobre esse problema dos getters e setters, o excesso de ifs e o relacionamento bidirecional entre
classes. Quer praticar tudo isso com video aulas, respostas dos instrutores e correção dos seus exercícios? Confira nosso novo curso online de boas
práticas de orientação a objetos!.
 Tweet 40
Tags: boas práticas, encapsulamento, fj-11, fj-15, getters e setters, orientação a objetos
32 Respostas para “Revisitando a Orientação a Objetos: encapsulamento no Java”
Rodrigo Ferreira
14. jun, 2012
Excelente post Mauricio!
Bem simples de entender.
É uma pena que ainda existam programadores java que acham que encapsulamento se resume a atributos private e métodos get/set público.
1.
Rafael Rossignol
14. jun, 2012
Concordo em todos os aspectos, porém os frameworks/apis de persistência nos obrigam a implementar getters e setters pra todos os atributos
que são persistidos, portanto, esse controle de encapsulamento ainda tem q estar na nossa cabeça, já que não podemos deixar de implementar o
setter
2.
Anderson Souza
3.
public void adiciona(Item item) {
 if (item.getValor() > 1000) this.valorTotal += item.getValor();
 else this.valorTotal += item.getValor() * 0.95;
 
 // nova regra de negócio aqui
}
Compartilhar
Revisitando a Orientação a Objetos: encapsulamento no Java | blog.cae... http://blog.caelum.com.br/revisitando-a-orientacao-a-objetos-encapsul...
3 de 8 27/2/2013 07:17
14. jun, 2012
Muito bom artigo! Só uma dúvida, se a regra diz que todos produtos com valor maior do R$ 1.000,00 recebe desconto, o ‘if’ do código da classe
Pedido não está invertido?
Carlos Antônio.
14. jun, 2012
Exelente post, está modo deve ser ótimo para JAVA, mas com certeza se encaixa muito bem em PHP e outras linguagens…
4.
Leonardo Nunes
14. jun, 2012
Ótimo artigo!
5.
Edinei
14. jun, 2012
Muito bom post !!!
É muito comum vermos isso no dia a dia, criar o atributo gerar os getter/setter (normalmente pela IDE) sem ao menos saber se de fato esses
atributos deveriam ser acessados diretamente pelo cliente. Onde na verdade métodos voltados para a lógica de negócio seriam os mais
indicados.
Acontece bastante isso também quando usamos collection em nossas classes e temos um set(Collection) e um getCollection expondo demais as
estruturas internas de um objeto, além de permitir os clientes manipularem o conteúdo das coleções diretamente sem ser o “dono” dessas
collections. Martin Fowler mostra isso no seu livro de Refactorings, para quem quiser ver:
http://sourcemaking.com/refactoring/encapsulate-collection
6.
RafaelPonte
14. jun, 2012
Como sempre muito simples e didático ao escrever sobre design de software – assunto este que sempre me chamou a atenção.
Só faltou você comentar que um código com encapsulamento bem definido pode ser facilmente testado através de testes de unidade.
Um post que também vale muito a pena ler é o post que o Phillip Calçado (aka Shoes) escreveu em 2008, http://blog.fragmental.com.br/2008/05
/18/objetos-nao-sao-atributos-funcoes/ .
Ah, como o Anderson Souza comentou, o if() do método adiciona() está invertido.
@RafaelRossignol
Na verdade já faz alguns bons anos que frameworks de persistência não te obrigam a ter getters e setters, como o Hibernate por exemplo.
Contudo, a maioria gritante dos frameworks MVC te obrigam a seguir o padrão JavaBeans, ou seja, você precisará de getters e setters.
No mais, excelente post, Aniche
7.
jonas
14. jun, 2012
Parabéns pelo post Mauricio Aniche
8.
Mauricio Aniche
14. jun, 2012
Olá galera, obrigado! Fico feliz que gostaram!
@Rafael Rossignol
Sim, infelizmente esse é um problema sério que temos: a infra-estrutura influenciando no nosso projeto de classes. Isso não deveria acontecer.
9.
Revisitando a Orientação a Objetos: encapsulamento no Java | blog.cae... http://blog.caelum.com.br/revisitando-a-orientacao-a-objetos-encapsul...
4 de 8 27/2/2013 07:17
Como citado acima, o Hibernate hoje até que não te força tanto, mas a maioria dos frameworks MVC pedem que vc tenha getters/setters nos
seus objetos. A sacada é pensar em como lidar com isso.
Momento plin-plin: O VRaptor te permite receber os dados pelo construtor, e assim você não precisa de setters aonde não quer.
Mas concordo em abosluto com teu ponto!
Mauricio Aniche
14. jun, 2012
Ah, e obrigado pessoal, o if estava invertido mesmo! Já arrumei!
“Cadê o teste desse código, Aniche!?” 
10.
Felipe
14. jun, 2012
Excelente, Maurício !
Amigo, posso utilizar esse conteúdo para uma aula que vou dar ?
Colocarei a fonte do seu site
11.
Mauricio Aniche
14. jun, 2012
Oi Felipe,
Claro que pode! Fico feliz que tennha gostado!
Um abraço!
12.
Herbert
14. jun, 2012
Sei que para bom entendedor, meia palavra basta. Mas nas primeiras linha de código existe um minúsculo erro:
Pedido c1 = new Pedido();
// muda valor do pedido para 200 reais!
c.setValorTotal(c.getValorTotal() + 200.0);
Foi criado objeto c1 e não c.
Muito bom o artigo, parabéns mais uma vez.
13.
Mauricio Aniche
14. jun, 2012
Corrigido, Herbert!
14.
Herbert
14. jun, 2012
só falta mudar o c.getValorTotal() para p.getValorTotal() também. Acho que não foi a toa que meu apelido no curso FJ11 era de “compilador”.
Abraços e parabéns novamente.
15.
Guilherme Mastria
14. jun, 2012
mas não é pra isso que utilizamos a classe de negócio?
instanciando uma DAO, convém colocar esse tipo de verificação dentro de um bean??
abraço
16.
Mauricio Aniche17.
Revisitando a Orientação a Objetos: encapsulamento no Java | blog.cae... http://blog.caelum.com.br/revisitando-a-orientacao-a-objetos-encapsul...
5 de 8 27/2/2013 07:17
15. jun, 2012
Oi Guilherme,
Por classes que negócio, vc quer dizer aquelas camadas onde enfiamos somente as regras de negócio, conforme sugerido por aquele catálogo de
padrões da Sun?
Infelizmente esses padrões promovem más práticas de código. Separar “regras de negócio” em uma camada e “dados” em outra, é voltar a
programar de maneira procedural!
E já sabemos os problemas desse paradigma: repetição de código, manutenção em diversos pontos diferentes, pois tudo está longe, e assim por
diante.
A discussão é parecida com a dos comentários acima. A infra estrutura sempre nos empurra a fazer mau uso da OO. Devemos lutar contra isso!
Respondi?
Gilmar M. dos Santos
15. jun, 2012
O post é muito bom, mas nada adianta saber disso, ser os frameworks mvc nos obrigado a implementar getters e setters.
18.
Paulo Vinícius Moreira Dutra
15. jun, 2012
Excelente post. Sempre presei o uso dos bons princípios da orientação a objetos. É uma pena ainda alguns frameworks nos obrigarem a usar
métodos getters e setters sem realmente ser necessário.
Um bom sistema OO, concerteza será mais fácil de dar manutenção.
E vamos utilizar o métodos getters e setters com moderação.
19.
Luiz
15. jun, 2012
Maurício,
Ótimo post.
20.
Luis Vasconcellos
15. jun, 2012
Perfeito. A ideia é encapsular dados e expor comportamento !
21.
Antonio Cesar
16. jun, 2012
Independente de frameworks e especificações que nos obrigam a utilizar “Más Práticas” um bom post e uma discussão inteligente sobre boas
práticas são sempre muito bem vindas….
Excelente post que estimula e valoriza o conhecimento bem utilizado… Parabéns….
22.
Raphael Lacerda
18. jun, 2012
Galera, apesar da maioria dos frameworks nos obrigarem a implementar os setters, vale lembrar que existem alternativas
http://www.guj.com.br/java/208491-iogi—usando-objetos-imutaveis-junto-com-o-vraptor
Excelente post… principalmente para quebrar mitos sobre atributos privados..
o q eu fico pé da vida é q os analista de mais alto nível dizem que o software precisa ter manutenibilidade…
agora, como vc vai explicar para o cidadao que encapsular sem usar setter vai te ajudar nesse quesito???
23.
Revisitando a Orientação a Objetos: encapsulamento no Java | blog.cae... http://blog.caelum.com.br/revisitando-a-orientacao-a-objetos-encapsul...
6 de 8 27/2/2013 07:17
Enfim, dae o q acontece na maioria dos projetos é q fica uma história para ingles ver… o cara pede manutebilidade e o programador diz q fez
um codigo totalmente manutivel seguindo os conceitos de “encapsulamento”
Mauricio de Mello
18. jun, 2012
A Ideia básica de um bom código é não repetir código, seja em java, c# ou linguagens não orientadas a objetos.
Ótimo post!!
24.
Henrique S.
26. jun, 2012
Excelente post!
25.
Rafael
28. jun, 2012
Parabens pelo otimos post.
26.
Guilherme Mastria
03. jul, 2012
…depende de empresa para empresa e principalmente dos canais de acesso que aquela DAO vai ter! Se você tiver o seu sistema simplesmente
Web, ok, tudo bem não ter o BO, mas você deixa o sistema altamente acoplado, ou seja, caso o seu sistema necessite de uma integração com
outro de uma empresa (que comprou a sua ou foi adquirida por) ou simplesmente seja acessado por um mobile, TV digital, Web e Desktop, e
com regras distintas… como o você faria? rs E hoje isso é bem propício.
27.
Mauricio Aniche
04. jul, 2012
Oi Guilherme,
Se você ainda não consegue trafegar a própria entidade de um lado pro outro (serializando em XML, JSON, ou coisa do tipo), aí vc cria uma
classe que só tem atributos e só serve unica e exclusivamente para navegar de um lado pro outro (os famosos DTOs).
Esconda a “sujeira” de converter sua entidade em um DTO, e pronto. Mas veja que essas classes não terão regra de negócio nenhum e só
servirão para transferir dados de uma camada para outra.
Faz sentido?
28.
Hélio Moura
23. jul, 2012
Muito bem colocado este seu exemplo Maurício.
Ótimo para aulas de orientação a objetos.
Saliento ainda que o uso de DDD (Domain Driven Design) vem crescendo justamente por permitir que boas práticas como esta possam ser
aplicadas.
O uso de DDD permite ao analista/desenvolvedor isolar de fato a camada de negócio, camada esta que é composta por classes completas, isto é,
com suas propriedades e comportamentos.
Este isolamente evita ter que se criar métodos de acesso às propriedades exigidos por certos frameworks, evitando assim, a quebra do
encapsulamento.
Venho utilizando DDD ultimamente e isto me tem remetido às origens da teoria da orientação a objetos onde o quê se procurava era apenas
oque hoje chamamos de boas práticas na orientação a objetos.
Vocês da Caelum fazem um excelente trabalho!29.
Mauricio Aniche
23. jul, 2012
Oi Hélio,
Obrigado! E concordo com vc: DDD faz o programador relembrar da boa e velha OO! 
Um abraço,
Mauricio
30.
Revisitando a Orientação a Objetos: encapsulamento no Java | blog.cae... http://blog.caelum.com.br/revisitando-a-orientacao-a-objetos-encapsul...
7 de 8 27/2/2013 07:17
Andre Alves Pinto
16. ago, 2012
Valeu Maurício!
31.
Maicon
19. ago, 2012
Parabéns pelo post Mauricio!! Explicou de forma simples e objetiva. abraços
32.
Deixar uma Resposta
 
 ASSINE NOSSO RSS
Facebook
Destaques
Por uma Web mais rápida: 26 técnicas de otimização de Sites
As Novidades do Eclipse Juno
Use CDI no seu próximo projeto Java
Flexibilidade em páginas para dispositivos móveis com media queries
Como não aprender Java e Orientação a Objetos: getters e setters
Usando o Google Maps e GPS no Android
Pixels, pixels ou pixels? Dicas de Web Mobile com viewport
Entenda os MVCs e os frameworks Action e Component Based
Os 7 hábitos dos desenvolvedores Hibernate e JPA altamente eficazes
As novidades do Hibernate 4
Siga-nos no Twitter
Caelum RSS Newsletter Contato
Revisitando a Orientação a Objetos: encapsulamento no Java | blog.cae... http://blog.caelum.com.br/revisitando-a-orientacao-a-objetos-encapsul...
8 de 8 27/2/2013 07:17

Continue navegando