Fluent interfaces em Delphi – 3 razões para você nunca mais deixar de usar

Fluent interfaces em Delphi - DevSpace
Fluent interfaces em Delphi - DevSpace

Última atualização em 29 de agosto de 2025 por Willian Tuttoilmondo

Uma das grandes vantages do desenvolvimento orientado a objetos é a possibilidade de criarmos fluent interfaces em Delphi. Assim como em outras linguagens de desenvolvimento que suportam o paradigma, Delphi também permite que recursos avançados sejam incorporados ao desenvolvimento, trazendo concisão, fluidez e, principalmente, facilidade de manutenção. O conceito é simples: até que se prove o contrário, qualquer método em uma interface deve ser uma função que retorna a instância desta mesma interface. Se você não está acostumado com o conceito de desenvolvimento orientado a interfaces, que é parte integrante do paradigma de desenvolvimento orientado a objetos, dê uma olhada aqui.

Neste artigo, vamos explorar o conceito de fluent interfaces em Delphi, com exemplos práticos, revisitando nossos códigos antigos, transformando-os em algo mais simples e natural.

Delphi e a orientação a objetos

O casamento do Delphi com o paradigma de orientação a objetos nasceu bem antes do próprio Delphi. Quando a Borland lançou a biblioteca TurboVision – você pode encontrar um manual do Turbo Pascal 6.0 com Turbo Vision aqui -, a orientação a objetos já estava lá. O Delphi já carrega consigo esse paradigma desde sua concepção e, o mais provável, é que as pessoas ignorem este fato e acreditem que nada do que o paradigma implementa seja possível de se fazer em Delphi. Mas, como sempre, isso é apenas um engano pavoroso e que, por muitas vezes, tem afastado profissionais e empresas desta tecnologia.

Mas, deixando a panfletagem de lado, vamos aos fatos.

Princípios de fluent interfaces em Delphi

Interfaces são estruturas de código que, em suma, definem um componente. Um contrato, se assim preferirem, que diz o que este componente tem a seu dispor, sejam métodos ou propriedades. Contudo, vale lembrar:

  1. Interfaces não têm construtores ou destrutores;
  2. Propriedades são sempre públicas e a interação com elas se dará, sempre, por getterssetters;
  3. Interfaces não admitem variáveis ou constantes e;
  4. Interfaces não implementam código.

Tendo isso em vista, construir fluent interfaces em Delphi deve obedecer, sempre, estas quatro regras e, além delas, uma quinta: até que se prove o contrário, todos os métodos da interface são funções que retornam sua própria instância. Em algum momento existirá um método que não será uma função ou, mesmo que seja, deva ter um retorno diferente, mas esses são casos “excepcionais” e serão tratados dessa forma de agora em diante.

Quando falamos sobre padrões de projeto em Delphi, vimos que podemos criar classes com estruturas idênticas para usar em uma abstract factory de modo a facilitar sua invocação e, por consequência, sua utilização. Então, partindo desse conceito, vamos transformar nossa “calculadora” em uma estrutura mais dinâmica usando fluent interfaces em Delphi.

Pra começarmos, vamos ver nossa classe de base.

Esse é um modelo clássico de classe, com propriedades e membros públicos e privados, com o qual estamos todos acostumados. Mas, lembrando que construir fluent interfaces em Delphi vai além de construir classes, vamos começar pelo começo: definindo nossa interface.

A implementação de interfaces por meio de classes tem apenas uma regra: todos os membros de uma interface, excetuando as propriedades, devem estar presentes na classe, mesmo que de forma abstrata. Sendo assim, ao redesenharmos nossa classe como uma interface, teremos:

As diferenças entre as duas abordagens são bem visíveis. Como estamos construindo fluent interfaces em Delphi, precisamos que todos os métodos que serão de visibilidade pública sejam transformados em funções e que retornem a instância da própria interface. A outra alteração está nas propriedades, antes marcadas como leitura/escrita e, agora, como apenas leitura. Com isso, os setters acabaram sendo tranformados em funções que, igualmente, retornam a instância da própria interface.

Assim, a implementação de uma classe baseada nesta interface tomaria esta forma:

Como já vimos no nosso artigo sobre interfaces, a implementação deve sempre partir de TInterfacedObject ou suas descendentes, implementando todos os membros que estão definidos na interface indicada na sua definição. Como não precisamos implementar as propriedades, pois estas já possuem visibilidade pública, a classe não precisa tê-las em seu contrato. Mas, caso você precise alterar esta visibilidade, elas deverão ser declaradas da mesma forma em que foram declaradas na interface, no escopo de visibilidade escolhido.

Outro detalhe, e este tem a ver com o conceito de SOLID, é que esta classe deve obedecer o conceito aberto/fechado, permitindo que descendentes estendam suas funcionalidades – e é para isso que temos os marcadores dynamicvirtual em Delphi -, evitando que alterações sejam feitas nela mesma. Ao final, teremos esta implementação para a classe base:

Um padrão de projeto aqui, outro ali e voilà!

Como já vimos os conceitos de abstract factoriessingletons anteriormente, não vou me estender revendo estes conceitos. Como nosso foco é desenvolver fluent interfaces em Delphi, vamos direto ao ponto. Nossa abstract factory, aqui, também obedecerá este conceito, ficando desta forma:

Implementando as operações básicas

Com o conceito de fluent interfaces em Delphi bem consolidado e com nossa estrutura de base já criada, vamos implementar as quatro operações básicas da matemática  – Adição, Subtração, Multiplicação e Divisão – seguindo o conceito criado por IOperacao.

É importante notar que todas as implementações descendentes de TOperacao não precisam definir novas interfaces. Elas apenas estendem a implementação do método Efetuar, aplicando, cada uma, sua operação para os termos A e B – e alertando o usuário de uma possível divisão por zero na classe TDivisao. Notem também que todas as implementações trazem Result := Self; como sua primeira linha, indicando que o retorno do método sempre será a instância da interface. Quando desenvolvemos fluent interfaces em Delphi, essa é a regra essencial.

Mas, e esse é o charme da coisa toda, a primeira razão para usarmos fluent interfaces em Delphi está na seção de inicialização do arquivo. E é sobre ela que falaremos a seguir.

Razão nº 1 para implementar fluent interfaces em Delphi: encadeamento

Como os métodos públicos implementados em uma classe retornam sua própria instância, podemos encadear as chamadas a estes métodos de maneira bem simples. Ao contrário do desenvolvimento tradicional, onde teríamos quatro linhas de código – uma para cada operação -, o compilador considerará esta como apenas uma linha.

A vantagem desta abordagem está na forma como as ferramentas de qualidade de código tratarão as fluent interfaces em Delphi, indicando que nosso código, por ter um número reduzido de linhas, vai se tornando menos tóxico e de manutenção mais simples.

Além disso, quando pensamos nos conceitos do código limpo e suas aplicações, o uso de fluent interfaces em Delphi nos traz o que é considerada a segunda razão para justificar seu uso.

Razão nº 2 para implementar fluent interfaces em Delphi: leitura aprimorada do código

Assim como nosso idioma é fluido, o uso de fluent interfaces em Delphi torna a própria linguagem fluida. Ler uma instrução onde cada operação realizada com um objeto é exposta sem a necessidade de uma nova linha de código e a invocação de sua variável de instância ou, pior ainda, usando uma estrutura with – nada contra seu uso, mas tente debugar algo com isso e sinta uma raiva imensa -, é de saltar aos olhos.

Logicamente isso só faz sentido, em termos de legibilidade, se você adicionar cada método em uma linha, como no exemplo. Caso contrário, isso será apenas uma linha muito extensa.

Com isso, chegamos na terceira razão para usarmos fluent interfaces em Delphi.

Razão nº 3 para implementar fluent interfaces em Delphi: a criação de DSLs

Uma DSL – do Inglês Domain-Specific Language – é uma linguagem de domínio específico, desenvolvida para tornar mais natural a leitura de instruções dentro da resolução de um problema. No nosso dia-a-dia, temos contato com várias delas, como SQL, HTML e CSS, por exemplo.

Quando usamos fluent interfaces em Delphi, criamos uma estrutura que se assemelha muito a uma DSL, pois a sintaxe criada difere do conjunto de instruções que todos conhecemos. Como usamos, por exemplo, TClasseDoObjeto.Instance.SetID(1) ao invés de VariavelDoObjeto := TClasseDoObjeto.Create e VariavelDoObjeto.Id := 1, acabamos por instituir uma nova sintaxe exclusiva para este domínio de informação, no caso, o componente que implementamos usando fluent interfaces em Delphi.

Isso só se dá pelo encadeamento das instruções, que é a nossa primeira razão, e impacta diretamente da legibilidade, nossa segunda razão. O fato é: usar fluent interfaces em Delphi nos garante um código limpo, eficiente e muito bem escrito.

Fluent interfaces em Delphi: uma aplicação prática

Usando fluent interfaces em Delphi, podemos transformar aquela nossa calculadora em um projeto com um código mais simples e funcional. Vocês vão notar que a legibilidade do código gerado é limpa, simples e fluida, como todo bom código deve ser.

Para começar, vamos desenhar o seguinte formulário:

Calculadora com Fluent Interfaces em Delphi - DevSpace
Calculadora com Fluent Interfaces em Delphi – DevSpace

Não se preocupem com as propriedades dos componentes. Como sempre, o código fonte estará disponível para download no final do artigo.

Mesmo assim, este é o código fonte do formulário:

Deem uma olhada no evento TCalculadora.btnCalcularClick, mais precisamente na linha 55. Ali vocês conseguem perceber o poder da implementação de fluent interfaces em Delphi. Com ela, foi possível interagir não com um, mas com dois objetos diferentes na mesma linha de instrução.

Ao invocar o singleton da abstract factory, foi possível chamar o método ObtemOperacao, o qual retorna um objeto derivado da interface IOperacao. A partir dele, foi possível invocar os métodos SetASetB, que atribuem os valores aos termos da operação e, em seguida, invocar o método Efetuar, o qual realizará a operação escolhida.

E tudo isso em apenas uma linha!

Fantástico, não é mesmo?

Ao realizarmos a análise da toxicidade do código, vemos que o evento TCalculadora.btnCalcularClick é o mais extenso, com 8 linhas, como mostrado abaixo.

Fluent interfaces em Delphi - Análise de toxicidade - DevSpace
Análise de toxicidade – DevSpace

Se não utilizássemos os conceitos de fluent interfaces em Delphi, este número seria de, pelo menos, 13 linhas. Num código simples como este, esse parece um ganho pequeno, mas se pensarmos em um software grande, as vantagens começam a fazer mais sentido.

Em operação, nossa calculadora tem este comportamento:

Calculadora utilizando fluent interfaces em Delphi - DevSpace
Calculadora utilizando fluent interfaces em Delphi – DevSpace

Ampliando as operações matemáticas

Depois de vermos como a implementação de fluent interfaces em Delphi pode trazer várias vantagens para o desenvolvimento, vamos nos divertir e ampliar nossa calculadora com mais duas operações: potenciação e radiciação.

Para tal, vamos criar um novo arquivo, como o que está abaixo:

E, sem alterar mais nenhuma linha de código na aplicação, teremos este resultado ao recompilarmos nossa calculadora:

Calculadora usando fluent interfaces em Delphi - Versão estendida - DevSpace
Extensão da calculadora utilizando fluent interfaces em Delphi – DevSpace

Legal, né?! Mas essa mágica só é possível quando as units que usam a seção initialization estão adicionadas ao projeto.

Em suma…

Implementar fluent interfaces em Delphi é simples e rápido. Isso tornará seu código mais limpo, legível e muito mais fácil de compreender. Mas, como gosto sempre de colocar em todos os artigos, usar fluent interfaces em Delphi vai depender, e muito, da maturidade dos profissionais envolvidos. É necessário entender que, antes de tudo, essa abordagem modifica a forma como enxergamos a linguagem de programação, o que pode ser um dificultador para desenvolvedores que estão muito presos ao modelo RAD.

Desenvolver utilizando fluent interfaces em Delphi não é o futuro. É o presente.

E como sempre, aqui vocês encontrarão o código fonte produzido neste artigo. Só um aviso: este código é compatível apenas com as versões mais recentes do IDE. Até o fechamento deste artigo, a versão oficial é a 12.3 Athens, a mesma utilizada na produção do código.

Até a próxima!

Sobre Willian Tuttoilmondo 13 Artigos
Arquiteto de software com mais de 25 anos de experiência em desenvolvimento de software, especialista em desenvolvimento multicamadas utilizando Embarcadero Delphi e NodeJS para o back-end e o próprio Delphi para o front-end. Usuário Linux desde 1998, é evangelista PostgreSQL, banco de dados no qual é especialista. Ocupa hoje a posição de arquiteto de software na TOTVS, a maior empresa de tecnologia do Brasil, além de ser sócio fundador da LT Digital Labs, empresa especializada em desenvolvimento e treinamentos.

Seja o primeiro a comentar

Faça um comentário

Seu e-mail não será publicado.


*