13 junho 2012

Conceito de Encapsulamento em POO (java)

Oi pessoal! Antes de mais nada, se desejar me seguir no twitter está aqui (@douglasddf)

Neste post vou comentar o conceito chamado Encapsulamento relativo a programação orientada a objetos (POO). Observem as perguntas iniciais:
  1. Por que encapsular informações em nosso programa? 
  2. Como fazemos isso na prática usando Java?
  3. É realmente necessário encapsular?

Essas questões são abordadas no vídeo que fiz (veja abaixo) para tentar responder as duas primeiras perguntas acima. Porém, a terceira pergunta é mais difícil de explicar. Alguém poderia dar uma resposta ou opinar sobre isso?






Encapsulamento, segundo Wikipédia (fonte: http://pt.wikipedia.org/wiki/Encapsulamento):
"Encapsulamento vem de encapsular, que em programação orientada a objetos significa separar o programa em partes, o mais isoladas possível. A idéia é tornar o software mais flexível, fácil de modificar e de criar novas implementações."
Ou seja, é uma forma de tornar visível para o usuário as funcionalidades que são importante para o sistema e somente isso. Em nosso exemplo, temos a classe Cliente que na prática, adicionou o tipo de acesso private do Java nos atributos e o tipo de acesso público nos métodos da classe. Só que foram criados um par de métodos (GET e SET) para recuperar e alterar, respectivamente, para cada atributo.

public class Cliente {

 // atributos para representar o cliente com acesso PRIVATE
 private String nome;
 private String CPF;
 private int quantidadePedidos;

 // para que se possa acessar os dados, criamos métodos PÚBLICOS get e set
 // para
 // cada atributo que se pretenda dar esse acesso

 /**
  * @return the nome
  */
 public String getNome() {
  return nome;
 }

 /**
  * @return the cPF
  */
 public String getCPF() {
  return CPF;
 }

 /**
  * @return the quantidadePedidos
  */
 public int getQuantidadePedidos() {
  return quantidadePedidos;
 }

 /**
  * @param nome the nome to set
  */
 public void setNome(String nome) {
  this.nome = nome;
 }

 /**
  * @param cPF the cPF to set
  */
 public void setCPF(String cPF) {
  CPF = cPF;
 }

 /**
  * @param quantidadePedidos the quantidadePedidos to set
  */
 public void setQuantidadePedidos(int quantidadePedidos) {
  this.quantidadePedidos = quantidadePedidos;
 }
 
 // operacoes que o cliente poderá
 // fazer neste sistema
 public void efetuarPedidoCompra() {
  System.out.println("efetuando pedido de compra");
  quantidadePedidos++;
 }

 // imprimir os seus valores
 @Override
 public String toString() {
  String atributosClasse = "Nome: " + nome + ", CPF: " + CPF
    + " , quantidade pedidos: " + quantidadePedidos;
  return atributosClasse;
 }

}


Isso simplesmente porque ao mudar o tipo de acesso aos atributos o Java não terá mais acesso a referência direta para LER e ESCREVER. Logo, temos que criar métodos para cada atributo GET e SET (sujestão de nome do Java). Desta maneira, quando precisarmos acessar (LER) o atributo do objeto usaremos:

  Cliente c = new Cliente();
  // acesso para ESCREVER (write)
  c.setNome("Douglas Frari"); 
  c.setCPF("222.222.222.11");
  
  // acesso para LER (read)
  System.out.println("Nome: "+c.getNome());
  System.out.println("CPF: "+c.getCPF());
  
  
  // ACESSO direto NAO é permitido pelo comilador java 
  // se não for da mesma classe. Logo, é preciso usar os SETs neste caso
  c.nome = "Douglas Frari";
  c.CPF = "222.222.222.11";
  

E quanto a pergunta 3 (É realmente necessário encapsular?)

É importante perceber que não é necessário encapsular para que o programa funcione. Mas é uma boa prática SIM encapsular os dados (atributos), pois assim tornamos o acesso DIRETO às referências dos objetos "seguros" do ponto de visto de escrita e leitura. O acesso somente será permitido usando os métodos públicos GET e SET.

5 comentários:

Thiago Burgos disse...

Só para gerar discussao:

Ter get e set vazios (ou burros, do ingles dumb) nao muda muita coisa. Qual a diferenca entre acessar diretamente um atributo publico ou acessar ele através de um get/set burro? no final das contas nao tem diferenca!

A questao principal é: Quando eu devo utilizar isso? O exemplo do teu vídeo mostra gets e sets "vazios". Qual um exemplo de caso onde encapsular realmente vai fazer a diferenca? :)

Unknown disse...

Ótima pergunta Thiago. Obrigado por participar dessa discussão.

Foi por isso que resolvi deixar a minha deixa da pergunta 3: É realmente necessário encapsular?

Eu citei no vídeo (no finalzinho), que dentro do SET poderíamos utilizar uma chamada de log com objetivo de registrar quem fez set. Assim podemos rastrear qual objeto o chamou.

Na prática eu vejo utilidade maior do Encapsulamento não nos métodos get e set, mas sim, nos métodos públicos que SOMENTE queremos prover as funcionalidades. Deixar PRIVADO coisas de negócio (caixa branca) e deixar o acesso a funcionalidade do que importa como PUBLICO.

Tens alguma outra visão sobre o encapsulamento que gostaria de complementar?

Muito obrigado! :D

Conexão Mocidade disse...

Muito boa a discussão Douglas o problemas estar nestes conceitos, muitos ainda nem sabem o que é realmente encapsulamento, não só esse mais muito outros conceitos, herança, usar construtor default ou não, na minha opinião encapsulamento é importando desde que os gets e sets sejam implementados para que não seja só uma pseuda segurança. Douglas ai vai um sugestão faz uma vídeo aula sobre herança e abre uma discussão sobre o assunto. valeu mestre, fica com DEUS!!!

Conexão Mocidade disse...
Este comentário foi removido por um administrador do blog.
Ketlen Patrícia disse...

Qual as principais características do encapsulamento?