Trabalhar com padrões dentro da programação é muito importante.
Nós vamos ver agora um pouquinho de JavaBeans,
que é a forma de padronizar a implementação do conceito
de encapsulamento de orientação a objetos.
Na programação Java, é usual criarmos classes
para que essas classes possam gerar objetos
a serem reutilizados em vários outros sistemas.
A especificação JavaBeans padroniza justamente a criação dessas classes,
que nós batizamos de classes beans.
Para fazer uma classe Java ser uma classe JavaBeans,
você precisa seguir três regras.
A primeira, é que essa classe precisa implementar um construtor padrão
mesmo que você tenha um construtor de classe.
Por quê? Porque outras APIs vão se utilizar desse construtor padrão
para criação de um JavaBean.
A segunda regra é o conceito de encapsulamento.
É necessário você encapsular os atributos, ou seja,
proteger esses atributos e permitir que outros métodos
acessem sim esses atributos.
E a terceira regra que, na realidade, é uma boa prática,
é você implementar a interface Serializable.
Essa interface vai marcar aquela classe como uma classe serializável.
O que significa isso?
Todos os dados que estiverem contidos no objeto
serão transformados em bits para serem trafegados
sem que a informação seja tão transparente.
Para entender um pouquinho mais a criação de uma classe
no padrão JavaBeans, vou criar uma nova classe chamada "pessoa"
dentro do projeto do sistema bancário.
Vou clicar no pacote aqui com o botão direito,
opção New, opção Class.
Vou nomear a classe com o nome pessoa e dar um finish.
Essa classe, por hora, é uma classe comum.
Mas eu vou criar o atributo nome da pessoa,
só que eu já vou criar no padrão JavaBeans,
ou seja, eu vou encapsular o atributo nome
para que nenhuma outra classe externa altere esse nome.
Então, eu declaro o modificador private,
declaro o atributo nome do tipo String,
e ele está protegido.
Nenhuma outra classe consegue alterar esse atributo.
Mas eu preciso, de alguma forma,
fazer com que esse atributo seja alterado,
mas simplesmente por algum método da própria classe.
É aí que eu utilizo os métodos padrões
chamados getters and setters.
O método get vai ser responsável por obter aquela informação
e o método set por alterar aquela informação.
Então, eu venho aqui e defino esses métodos.
Vou definir manualmente e depois eu vou mostrar
como fazemos automaticamente.
Ambos os métodos têm modificadores públicos
justamente para serem acessados fora do escopo dessa classe.
O método get vai retornar o tipo de dado
justamente do atributo em questão, que é o atributo nome.
Então, vai ter um retorno String e o nome vai ser "getNome".
Ele não vai ter nenhum parâmetro,
e a grande lógica dele é retornar o nome daquele atributo da pessoa.
Vou criar aqui também o que chamamos de método set.
Esse método não vai ter nenhum retorno.
Vai ter o prefixo set mais o nome do atributo que eu quero trabalhar,
e ele tem que receber como parâmetro
o novo nome que será associado.
E a lógica desse método é:
eu alterar o atributo nome da classe
pelo novo nome que veio de parâmetro.
Nesse exemplo, nós criamos então o atributo nome, privado,
e demos dois métodos de acesso a esse atributo nome.
Você pode pensar: "Poxa, mas esses métodos
estão simplesmente fazendo o acesso
de obter e de alterar a informação".
Ok, mas eu posso colocar mais lógicas dentro dos métodos,
ou seja, o atributo não vai ser acessado diretamente,
mas esses métodos podem, além de alterar o atributo,
fazer outras lógicas a respeito desse atributo.
E para que essa classe realmente tenha
a característica de uma classe JavaBeans,
eu preciso implementar a interface Serializable,
que vai marcar aquela classe como uma classe serializável.
Então, eu adiciono lá o implements,
adiciono a interface Serializable,
que está dentro do pacote java.io.
E, com isso, essa classe já é marcada como serializável,
ou seja, quando eu gerar um objeto a partir dessa classe pessoa,
as informações desse objeto serão serializáveis,
transformadas, de fato, em pacotes de bits para serem trafegados pela rede.
Note que, ao implementar a interface Serializable,
aparece em amarelinho o nome da classe.
Isso significa o quê?
Que a classe está requisitando algum identificador de serialização.
Por que isso acontece?
Porque eu posso ter num mesmo ambiente de memória
mais de um objeto da classe pessoa com versões diferentes.
Então, com isso, eu consigo identificar qual versão é aquele objeto
para que os objetos não se confundam.
Então, eu posso simplesmente pegar a opção que o próprio Eclipse me dá,
que é adicionar um default serialVersionUID.
E aí você pode colocar a identificação
que melhor for compatível com o seu projeto.
Agora, eu vou fazer o seguinte:
vou alterar o código do meu sistema bancário
da classe conta e da classe teste
para ser colocado no padrão de JavaBeans.
Vou acessar a minha classe conta,
e na classe conta eu vou fazer as devidas alterações.
A primeira coisa que eu devo fazer é deixar encapsulado todos os atributos.
Então, eu vou colocar o assessor private
em todos os atributos do escopo da minha classe.
Então, private dentro de agência, para o número da conta e para o saldo.
Dessa forma, nenhuma dessas informações pode ser alterada diretamente.
Notem que, logo que eu protejo esses atributos,
a classe teste passa a dar erro.
Por quê? Porque tanto o saldo, quanto a agência, quanto o número,
não são mais acessíveis diretamente.
E isso está ok.
Outra coisa que eu preciso fazer aqui
é trabalhar com os métodos getters and setters.
Mas é claro que eu preciso identificar
se todos eles são válidos de serem colocados ou não.
Por exemplo: eu posso permitir a alteração de um saldo diretamente?
Ou esse saldo só pode ser atualizado
através de um depósito ou de uma retirada?
Nesse caso, eu não preciso ter um método setSaldo,
mas eu posso ter um método getSaldo.
E aqui eu também posso ter os métodos setAgencia, getAgencia,
setNumero, getNumero.
Nós podemos fazer essas alterações na programação
ou eu posso fazer a geração automática dos getters and setters.
Para fazer a alteração automática dos getters and setters,
eu posso fazer de duas maneiras.
Eu posso clicar com o botão direito no código,
ir à opção Source, Generate Getters and Setters,
ou, ainda, através do atalho Ctrl + Shift + S.
Uma vez selecionada a opção Generate Getters and Setters,
eu seleciono quais os atributos que eu quero gerar os getters and setters.
Nesse caso, eu quero simplesmente gerar da agência e do número.
Clico em ok, e ele gera automaticamente
os métodos getAgencia, setAgencia,
getNumero, setNumero.
"Mas, professor, e o método getSaldo e setSaldo?".
Nesse caso, para fazer as devidas adaptações,
eu vou simplesmente substituir
o nome do método verificarSaldo para getSaldo,
e a alteração do saldo já está sendo realizada
através dos métodos retirar e depositar.
Portanto, eu não preciso criar o método setSaldo.
Para que essa minha classe vire, de fato, um JavaBean,
eu ainda preciso implementar a interface Serializable.
Então, basta fazer o implements
na interface Serializable.
Eu posso completar com um Ctrl + espaço,
e também posso implementar o meu controle de versão.
Pois bem, agora vamos adaptar a classe teste
para que ela possa usar a classe conta
da maneira correta no padrão de JavaBeans.
Então, ao invés de eu acessar diretamente o atributo,
eu posso simplesmente setar essas informações.
Ao invés de colocar o saldo como 50,
então eu vou setar o método depositar...
... com o valor 50.
Então, não vai ser mais possível eu alterar diretamente um atributo.
Também vou dar um set na agência
passando o valor daquela agência dentro do método
e também o número da conta através do método setNumero.
Com isso, quaisquer lógicas que eu tenha que fazer
dentro da alteração de uma agência ou dentro da alteração de um número,
ou até no saldo, eu consigo fazer dentro desses métodos previamente criados,
gerando assim, uma segurança e uma melhor manutenção.
E uma última alteração a ser realizada aqui
é alterar o método verificarSaldo para getSaldo
em ambos os objetos que estamos trabalhando.
"Ah, professor, eu preciso alterar alguma coisa do construtor de classe?".
Nesse caso, não, porque o construtor de classe já está utilizando
e alterando os atributos da própria classe.
Vou realizar o teste aqui, e é possível verificar
que não houve alteração no resultado.
Simplesmente implementamos um padrão
que é muito utilizado no mercado de programação Java.
Duas dicas muito importantes a respeito do padrão JavaBeans.
Primeira: nem todas as classes devem ser colocadas nesse padrão.
Somente aquelas classes que carregam informações,
ou seja, que serão gerados objetos em memória
para armazenar e carregar informações.
E a segunda dica é que, toda essa estrutura de padrões,
não deve ser pensada diretamente na programação.
Isso pode ser realizado durante a análise do sistema
desde o ato da criação de diagramas de classes,
onde eu já consigo identificar toda a parte de construtores,
de encapsulamento, e também da geração dos métodos.