Tipos Primitivos nos Argumentos


Se os Objetos conversam entre si utilizando mensagens, ou seja, através dos seus Métodos, por que utilizaríamos Tipos Primitivos nos argumentos desses Métodos ao invés de utilizarmos Objetos?

Unsplash image

Introdução

Os Objetos conectam-se uns aos outros através de seus construtores e Métodos, enviando argumentos uns aos outros.

No paradigma da Orientação a Objetos, tudo são Objetos. Inclusive os argumentos. Bem, deveriam ser, pelo menos na maioria dos casos.

Imagine um um formulário onde o usuário precisa digitar seu login. Esse formulário, que contém Objetos visuais para capturar a digitação, irá enviar o login digitado à outro Objeto para validar a identificação.

Seria o login um Objeto ou apenas texto?

Você pode pensar que o login é apenas uma informação simples, um tipo string, apenas texto puro, não havendo necessidade de um Objeto.

Mas, não seria esse “texto puro” também um Objeto?

Tudo são Objetos na Orientação a Objetos.

Confuso?

Argumentos

Tudo são Objetos, mas nem sempre os requisitos são implementados como tal. Os motivos são diversos, mas simplicidade e performance sempre são citados como motivos plausíveis para o uso de tipos primitivos nos argumentos.

Utilizar tipos primitivos nos argumentos é um anti-padrão chamado “Primitive Obsession”.

Então vamos ver esses motivos e tentar dismitificá-los.

Performance

É claro que Objetos são “mais lentos” para trabalhar e consomem “mais recursos” que os tipos primitivos. No entanto a Orientação a Objetos é sobre a arquitetura do sistema, deixando a performance por conta do compilador e código de máquina gerado.

A diminuição da performance — mesmo que mínima — em sistemas Orientado a Objetos é um preço justo a se pagar devido a melhoria na arquitetura que o paradigma da Orientação a Objetos nos traz.

Na minha experiência, utilizando Objetos pequenos e simples, que implementam apenas uma única responsabilidade, não há perda de performance significativa.

Mas, ainda assim, se seu maior requisito for performance, talvez a Orientação a Objetos não sirva para seu projeto… talvez.

Simplicidade

Seriam os tipos primitivos mais simples de usar do que Objetos?

De acordo com a minha experiência, na maioria das vezes, não.

Pense bem: Quantas vezes você teve que passar uma “Data de Nascimento” como argumento de um Método e lá dentro ter que convertê-la em String, por exemplo, para exibir ao usuário?

Quantas vezes passou um “Nome Completo” por parâmetro como sendo apenas uma String mas depois teve que usar uma função Copy porque só queria exibir o “Primeiro Nome” ou a primeira parte do nome?

Sem falar na repetição de código que poderia ocorrer com o uso dessas funções auxiliares em várias partes do código.

Com Objetos seria muito mais simples.

Veja. Um Objeto “Data de Nascimento” seria responsável por algum cálculo de idade, além de retornar a si mesmo no formato String.

Um Objeto “Nome Completo” seria responsável por retornar o primeiro nome e sobrenome; talvez retornar tudo em maiúsculo seria outro Método.

Quer outro exemplo?

Trabalho bastante com GUID’s. Elas são utilizadas em meus sistemas como chaves-primárias de registros.

Se não me engano, o tipo TGuid no Object Pascal é um record. Não lembro, pois eu não o utilizo mais, não diretamente.

Eu tenho minha própria Classe TDataGuid que implementa uma Interface IDataGuid.

Essa Classe tem alguns construtores com argumentos diferentes para inicializar o estado do Objeto, que internamente é um TGuid. Posso receber uma String com ou sem “{…}”, posso receber um TGuid ou mesmo não receber nada e inicializar o estado internamente.

Por quê um Objeto ao invés de um “simples” record?

Nos meus sistemas, um GUID tem comportamento. Ele não é apenas um dado.

Por exemplo. Para exibição de um GUID para o usuário basta utilizar o Método AsString. Se eu quiser exibir apenas o “formato de digitação” — os 8 primeiros caracteres — basta utilizar o Método AsShortString. Se eu quiser o próprio TGuid basta chamar Value.

Seria mais simples ficar fazendo conversões por todo o código utilizando funções auxiliares ou utilizar um Objeto como esse?

Acho que não há dúvidas aqui.

Conclusão

Quando você implementa Objetos da forma correta, o código é simplificado.

Essa ideia vai contra o pensamento da maioria dos programadores procedurais que acham que utilizando tipos primitivos e funções deixaria o código mais simples de entender e alterar.

Ledo engano.

É claro que podemos e devemos utilizar os tipos primitivos, mas utilíze-os apenas como argumentos de Métodos privados, variáveis locais ou para Classes de infraestrutura.

Para a comunicação entre Objetos de Negócio, utilize Objetos.

Até logo.

Posts Relacionados

  • Memória Segura Utilizando Instâncias de Interfaces

  • Classes Mutáveis vs Objetos Imutáveis

  • Implementando Interfaces Utilizando Diferente Assinaturas de Métodos

  • Usando Paths ao invés de Diretivas de Compilação

  • Trabalhando com Exceções em Requisições HTTP

  • Tipo object Continua Vivo

  • Array de Objetos

  • Variáveis Locais Deveriam ter Nomes Curtos

  • Como Dividir e Organizar o Código em Formulários com Muitos Widgets

  • Pascal Deveria ser Modernizado?