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.