DEV Community

Cover image for DSL (Domain-Specific Languages) - Mergulhando
Rafael Rodrigues de Oliveira
Rafael Rodrigues de Oliveira

Posted on • Updated on

DSL (Domain-Specific Languages) - Mergulhando

Aprofundando na série de artigos dedicados às Linguagens de Domínio Específico (DSLs).

No nosso artigo inaugural, intitulado "DSL - O Início", fornecemos uma explicação elementar sobre as distinções entre DSLs Internas e DSLs Externas. No entanto, dado o escopo restrito que abordamos apenas as DSLs Internas, é necessário um aprofundamento maior nesse conceito.


DSLs Internas

 

As DSLs Internas são limitadas pelas restrições impostas pela linguagem hospedeira, que pode ser uma linguagem de programação como Java, C#, Ruby, entre outras.

Quais são essas restrições?

Toda linguagem possui suas particularidades, as quais servem para restringir o que é considerado válido ou inválido na linguagem. Como uma DSL Interna depende de uma linguagem hospedeira, as expressões utilizadas devem ser válidas naquela linguagem específica.

Neste artigo, utilizarei Java como linguagem hospedeira nos exemplos, onde todas as expressões empregadas nas DSLs devem ser compatíveis com a sintaxe e semântica do Java.

Antes de apresentar exemplos de construção de uma DSL, é importante discutir sobre o conceito de Interface Fluente.


Interface Fluente

 
Possivelmente, em algum momento da sua carreira como desenvolvedor, você já se deparou com o termo "Interface Fluente" e pode tê-lo associado ao encadeamento de métodos. Essa associação não está incorreta, uma vez que a técnica de encadeamento de métodos é utilizada na construção de uma Interface Fluente.

No entanto, é crucial compreender que a Interface Fluente não se limita apenas ao encadeamento de métodos, mas sim à fluidez do fluxo resultante desse encadeamento. Ao realizar chamadas encadeadas, é essencial ter a sensação de um fluxo contínuo e harmonioso.

É importante destacar que o encadeamento de métodos não é a única abordagem para criar esse fluxo. Existem outras técnicas que podem ser empregadas.

Para consolidar o entendimento, a Interface Fluente diz respeito à fluidez do fluxo, enquanto o encadeamento de métodos é apenas uma das técnicas utilizadas para alcançar esse fluxo.

É possível encadear métodos sem obter a fluência desejada, nesse caso, não se trata de uma Interface Fluente, mas apenas da utilização da técnica do encadeamento de métodos.


E qual a diferença das DSLs Internas para Interface Fluente?

 
Portanto, essa distinção depende do contexto.

O que quero dizer com isso? Quando nos encontramos dentro do âmbito do domínio e criamos expressões baseadas nesse contexto, considero isso como uma DSL Interna. No entanto, quando desenvolvemos expressões que não estão diretamente relacionadas ao domínio, mas são empregadas para a construção de uma API com maior fluência, em vez de utilizar uma API de Comando-Consulta (termo cunhado por Martin Fowler), estamos, então, utilizando uma Interface Fluente.

Essa é a minha maneira de pensar e diferenciar esses dois conceitos. É possível que você encontre interpretações distintas, pois esse é um tema que pode gerar amplas discussões e diferentes pontos de vista.

 

API Comando-Consulta

 
De maneira geral, uma API Comando-Consulta consiste em métodos de um objeto que podem retornar um valor sem modificar o estado do objeto (consultas) e métodos que modificam o estado do objeto sem retornar um valor (comandos). As consultas são responsáveis por obter informações e podem ser chamadas várias vezes sem afetar o estado do objeto, enquanto os comandos requerem cautela ao serem invocados devido aos efeitos colaterais que podem gerar.

Essa abordagem permite separar os métodos que não possuem efeitos colaterais (consultas) daqueles que os possuem (comandos). Os métodos getters e setters são exemplos desse tipo de separação.
 


Todas essas formas de expressão de uma DSL, como encadeamento de métodos, função aninhada e sequência de funções, são conhecidas como construtores de expressões. Esses construtores de expressões são objetos cujo objetivo é construir objetos comuns utilizando uma Interface Fluente.

No próximo artigo, abordaremos com mais detalhes esse conceito.


Formas de Construir DSL Interna

 

Sequência de Funções

  email();
    de("remetente@email.com");
    para("destinatario@email.com");
    assunto("E-mail Sequência de Funções");
    mensagem("E-mail para Teste");
  enviar();
Enter fullscreen mode Exit fullscreen mode

Encadeamento de Métodos

  email()
    .de("remetente@email.com")
    .para("destinatario@email.com")
    .assunto("E-mail Sequência de Funções")
    .mensagem("E-mail para Teste")
  enviar();
Enter fullscreen mode Exit fullscreen mode

Funções Aninhadas

email(
       de("remetente@email.com.br"), 
       para("destinatario1@email.com.br", "destinatario2@email.com.br"),
       assunto("E-mail Teste"),
       mensagem("Esse E-mail serve para teste do Modelo Semântico")
      );
Enter fullscreen mode Exit fullscreen mode

 
É importante ressaltar que é possível combinar essas técnicas para a construção de uma DSL.

Agradeço sinceramente pela leitura e espero que este artigo tenha sido do seu agrado.

Referência

Top comments (0)