Fala galera!
Quando iniciamos nossos estudos de Orientação a Objetos aprendemos que classes e objetos possuem dados e comportamentos.
Isto é sim verdade, mas da forma que. Isto é listado, os exemplos e tudo mais parece que a parte mais importante são os dados, mas será que isto é verdade?
Dando um passo atrás devemos lembrar sempre que ao modelar uma classe devemos ter em mente o contexto onde ela será utilizada, o qual normalmente chamamos de domínio, de forma a termos uma visão clara do mesmo.
Nem todos os nossos sistemas precisam ter acesso a todos os dados do cliente, alias apensar do reuso ser algo que está no DNA da Orientação a Objetos não é crime nenhum termos diferentes versões de uma mesma classe, como o Cliente que é usado na Nota Fiscal, o Cliente que é usado no módulo de Entrega, o Cliente utilizado pelo sistema Financeiro, cada um com um grupo de dados, e comportamentos, diferenciados.
Outra coisa importante é lembrar que um objeto representa o estado de algo em um determinado momento no tempo. Ao carrega-lo do sistema de persistência ele representa aquele item naquele exato momento, e a partir de que começamos a manipula-lo através da chamada de seus métodos, ele sofrerá alterações e deve ainda permanecer em um estado válido para posterior persistência.
É por isto que hoje ouvimos tanto falar em Setters privados, encapsulamento dos comportamentos, garantia de que não quebraremos o estado.
Mas fui além do que queria falar no inicio deste artigo.
O ponto central aqui é que por começarmos nossa modelagem pelos dados corremos dois riscos: colocarmos em nossas classes dados que achamos que iremos utilizar e transformamos nosso objeto em uma sacola de dados.
A abordagem que gostaria que vocês experimentassem aqui é a de começar modelando suas classes po seus comportamentos, ou seja, quais mensagens usarei para me comunicar com ela.
Com isto já consigo visualizar dois itens importantes: quais parâmetros estes métodos receberão? E destes parâmetros qual estado deverá ser alterado e persistido.
Se te pedisse para modelar uma classe de Conta Corrente com toda certeza voce começaria com os dados do correntista, da agencia, etc., etc.
Mas e se dentro do contexto que estamos desenvolvendo, talvez um microserviço que cuide apenas de manipular o saldo desta conta, com serviços como Depositar uma quantia e Sacar uma quantia, a coisa já muda de figura, certo?
Então temos aqui uma classe Conta com dois métodos, Depositar e Sacar.
Curiosamente os dois métodos recebem um valor monetário, o valor a ser depositado ou retirado da conta.
Como resultado teremos o Saldo desta conta atualizado e persistido.
Logo teremos também um atributo, preferencialmente privado, com este Saldo.
Algo como:
Classe Conta { void Depositar(decimal valor) => Saldo = Saldo + valor; void Sacar(decimal valor) => Saldo = Saldo – valor; private decimal Saldo = 0; }
Sim, bem simples, bem rudimentar, mas que me parece ser funcional.
Agora vamos pro segundo ponto. E se por um erro sistêmico eu passar um valo negativo tanto para Depositar como Sacar? E se eu tentar sacar um valor maior do que meu saldo atual? Colocarei minha conta corrente em um estado inválido.
É por isto que o encapsulamento de como minha classe funciona é tão importante. Com isto eu garanto que qualquer parte do meu sistema não irá bagunçar meu estado interno e com isto tenho um maior controle do qu está acontecendo, reduzindo a possibilidade de erros.
O encapsulamento também me traz mais benefícios. Consigo realizar testes de maneira mais isolada e eficaz já que. Reduzo a possibilidade de alterações de estado involuntário tornando os resultados previsíveis.
Em nossa classe como não conseguimos alterar o saldo sem chamar Depositar ou Sacar, independente de como eu fizer minhas operações, eu sempre obterei o mesmo resultado.
Não estou falando aqui d concorrência e outros desafios do mundo moderno, mas se não conseguimos visualizar estes problemas já em abstrações mais básicas, a coisa se torna muito mais complicada em versões mais completas e complexas deste modelo.
Espero ter ajudado!
Até a próxima!