Como fazer uso de tipos de dados mais expressivos
Tipos de dados usados de forma mais expressiva, potencialmente melhoram o entendimento e a manutenção do código fonte de uma aplicação.
Certamente que a experiência traz mudanças na forma como pensamos e escrevemos nossos códigos.
Hoje quero compartilhar minha vivência em relação a algo pouco discutido mas bastante importante: tipos de dados.
Tipos de Dados Primitivos
Nas linguagens de programação, são os tipos básicos (nativos) utilizados para armazenar em memória os dados das variáveis. Como exemplo, no C# temos: int, short, bool, char, string etc.
Com eles, é possível construir estruturas de dados robustas, que nos permitem abstrações mais complexas.
Veja a classe Conta abaixo, formada somente por tipos nativos. Ela é bem simples, contendo apenas informações essenciais sobre uma conta qualquer.
public class Conta { public string Fornecedor { get; set; } public string Numero { get; set; } public decimal Valor { get; set; } public DateTime Vencimento { get; set; } public DateTime Pagamento { get; private set; } public string Situacao { get; private set; } public Conta() { Situacao = "EmAberto"; } }
Inicialmente, essa implementação parece atender as necessidades, mas no decorrer da evolução do sistema alguns problemas podem surgir.
Observe a propriedade Numero, nós podemos atribuir qualquer dado texto a ela, o que nos levaria a coisas como: “12345”, “12 3 45”, “1234-5”. Ou seja, a representação da informação fica dúbia e custosa de se manter.
Por que então não colocamos o tipo como inteiro, assim, unicamente números podem ser alocados? Bem, Numero é o identificador da conta, entretanto, não necessariamente é de fato um número.
Como então, poderíamos resolver casos como esse? Veremos isso a seguir.
Tipos de Dados Expressivos
Algumas linguagens nos permitem compor tipos mais adequados ao domínio da aplicação. Sendo assim, vamos nos utilizar disso na nossa classe Conta.
public class Conta { public Fornecedor Fornecedor { get; } public IdentificadorDeConta Numero { get; } public decimal Valor { get; set; } public DateTime Vencimento { get; set; } public DateTime Pagamento { get; private set; } public SituacaoConta Situacao { get; private set; } public Conta(Fornecedor fornecedor, string identificador) { Situacao = SituacaoConta.EmAberto; Fornecedor = fornecedor; Numero = fornecedor.ObterIdentificador(identificador); } } public enum SituacaoConta : byte { EmAberto, Paga } public class Fornecedor { public string RazaoSocial { get; set; } public string NomeFantasia { get; set; } public IdentificadorDeConta ObterIdentificador(string identificador) { var valido = ValidarIdentificador(identificador); if (!valido) throw new ArgumentOutOfRangeException($"Identificador '{identificador}' não é válido."); return new IdentificadorDeConta(identificador); } private bool ValidarIdentificador(string identificador) { throw new NotImplementedException(); } } public struct IdentificadorDeConta { public string Identificador { get; } public IdentificadorDeConta(string identificador) { Identificador = identificador; } }
Veja como pequenas alterações já nos permitem sermos mais expressivos.
Substituímos o string da Situação pelo enum SituacaoConta, onde está mais claro quais opções temos para o dado que queremos guardar. E, ainda, evitamos que seja informado um dado não condizente.
Também, alteramos o tipo do Fornecedor que, além de ser mais representativo, nos permite atribuir mais informações do que apenas o nome, como anteriormente.
Demos, adicionalmente, ao tipo Fornecedor a responsabilidade de gerar o IdentificadorDeConta, impedindo que esse seja construído de forma errada.
Complexidade Aparente
Pode ser contraintuitivo, em muitos casos, o aumento da complexidade para ganhos tão pequenos na expressividade. Mas, não se engane, tipos primitivos “escondem” muita informação.
Acredito, o tipo string ser o pior deles, visto que podemos guardar virtualmente qualquer valor nele. Portanto, saber abstrair tipos mais concisos com o domínio é fundamental para o desenvolvimento.
De outra forma, manter tipos primitivos em excesso, pode causar o “vazamento do domínio”, um tema crucial, mas para outra discussão.
Espero que tenha conseguido elucidar um pouco o tema. Deixe seus comentários abaixo, ficarei feliz em responder. Até a próxima.
Os comentários estão fechados, mas trackbacks E pingbacks estão abertos.