https://a.storyblok.com/f/270183/93989/d0a80acb87/boost-productivity-model-driven-engineering-p1.png

Aumente sua produtividade com a engenharia orientada a modelos (Parte 1)

Publicado em January 17, 2024

Tempo de leitura: 11 minutos

Introdução

Quando questionados sobre nossa profissão, nós, como desenvolvedores, não temos falta de opções de termos para nos descrever. Podemos nos descrever de várias maneiras: “Desenvolvedor de Software”, “Programador de Computador”, “Cientista da Computação”, “Codificador”, “Engenheiro de Software” ou outras funções mais especializadas, como “Arquiteto de Software”, “Engenheiro de DevOps”, “Defensor de Desenvolvedores”, etc. Às vezes, usamos esses termos de forma intercambiável ou escolhemos aquele que mais nos identifica. Mas, quando se pensa nisso, será que “Programador de Computador” é realmente a mesma coisa que “Engenheiro de Software”? Em muitos casos, pode ser. Eu, assim como muitos, se não a maioria dos desenvolvedores, adoro programar intensamente. É, sem dúvida, a pedra angular da nossa profissão e o que atraiu muitos de nós para essa área de atuação.

No entanto, é importante reconhecer que essa área se baseia em abstrações. À primeira vista, o trabalho de um programador de computador mudou drasticamente desde os primórdios dos cartões perfurados. A maioria de nós não conhece Assembly nem mesmo C — que na época (e ainda hoje) era considerada uma linguagem de programação de “alto nível”. A tarefa de um programador (ou “codificador”) é, em última análise, transmitir instruções ao hardware subjacente para que ele execute determinadas operações. No entanto, não é assim que a maioria de nós encara nosso trabalho no dia a dia. Em vez disso, pensamos em um nível mais elevado de abstração — em termos de soluções. Assim, a programação, por mais divertida e desafiadora que seja, é um meio para atingir um fim. Por isso, o termo “engenheiro de software” é um conceito mais abrangente que engloba todo o processo de desenvolvimento. Se a engenharia de software é como construir uma casa, então a programação é a parte em que se assenta os tijolos.

Infelizmente, a programação nem sempre é divertida ou propícia à resolução de problemas. Especialmente no caso de linguagens verbosas como Java, muitas vezes é uma tarefa enfadonha. Isso se deve ao código padrão: código que é repetitivo e tedioso de escrever manualmente, mas ainda assim necessário e útil. Esse costuma ser o aspecto menos produtivo da programação e, coincidentemente, o mais passível de automação. Embora os IDEs sejam bons na geração de código padrão comum, como getters e setters, toString(), equals e hashCode(), elas só conseguem atender às necessidades genéricas comuns da linguagem, não do domínio. Se ao menos houvesse uma maneira de eliminar o processo tedioso de escrever manualmente código padrão específico do domínio...

O que é Engenharia Orientada a Modelos?

A Engenharia Orientada a Modelos (MDE) é uma disciplina que promove que os modelos como artefatos de primeira classe no processo de engenharia, elevando assim o nível de abstração. Quando aplicada à engenharia de software, isso significa que, em vez de código-fonte ser o principal artefato de interesse, nos preocupamos mais com o modelo de domínio.

Embora o MDE seja frequentemente um termo e uma disciplina acadêmica, ele tem ganhado maior destaque por meio do termo “low-code” — algo de que os acadêmicos também estão cientes. Pode-se argumentar que o MDE tem um escopo mais amplo do que o movimento low-code, mas, na prática, essas diferenças semânticas costumam ser de interesse acadêmico — desculpem o trocadilho!

Então, você deve estar se perguntando: o que é um modelo? Bem, é qualquer coisa que descreva o domínio de forma declarativa. Você pode pensar em um modelo como dados específicos do domínio. O importante é que esses dados estejam estruturados de maneira previsível. Na linguagem do MDE, chamamos essa estrutura de metamodelo. O metamodelo é, ele próprio, um modelo que descreve a “planta” do domínio – da mesma forma que a planta de um arquiteto serve de guia para a construção de um prédio. Para deixar isso mais claro, vamos considerar alguns exemplos.

Metamodelos

A ideia de um metamodelo é restringir o que pode ser expresso ao se utilizar ferramentas e linguagens de uso geral. Exemplos de tecnologias de metamodelagem incluem Esquema XML (XSD), o JSON Schema ou qualquer esquema de banco de dados. É isso mesmo: se você já trabalhou com um banco de dados relacional, um documento XML ou qualquer tipo de arquivo de configuração, já está familiarizado com esse conceito, mesmo que talvez não tenha pensado nisso nesses termos.

Existem muitos exemplos disponíveis; no entanto, por uma questão de concisão e para fins ilustrativos, não os apresentarei diretamente aqui. Mas quando você começar a pensar em esquemas como metamodelos e os dados estruturados que se enquadram nesses esquemas como modelos, isso pode fazer sentido intuitivamente. Considere o arquivo “CustomersOrders.xsd” deste tutorial. Esse arquivo está, de fato, modelando os Concepts do domínio e como eles se relacionam entre si. O arquivo “CustomersOrder.xml” é uma instância disso — um modelo que está em conformidade com o "CustomersOrders.xsd" metamodelo. Se você estiver familiarizado com programação orientada a objetos, pode pensar nos metamodelos como classes e nos modelos como objetos (ou seja, instâncias dessas classes). Na programação orientada a objetos, uma classe define o esquema para instâncias concretas (objetos). Outro exemplo é este esquema JSON mínimo. Ele define uma Pessoa que possui três propriedades: firstName, lastName e age.

Nesses dois casos, você percebeu que o próprio metamodelo é escrito na mesma linguagem que o modelo? Ou seja, um arquivo XSD usa a mesma sintaxe do XML, e um JSON Schema é escrito em JSON! A consequência disso é que os próprios metamodelos são modelos que se enquadram em um meta-metamodelo. Incrível, não é? Em outras palavras, existe um esquema para o metamodelo. Felizmente, na maioria dos casos, esse meta-metamodelo de nível superior é geralmente onde tudo termina. Os meta-metamodelos geralmente estão em conformidade consigo mesmos. Não é brincadeira — existe literalmente um arquivo XSD que define o metamodelo para os XSDs!

Estrutura de Modelagem Eclipse

Tendo definido o conceito principal da engenharia orientada a modelos, vamos agora nos voltar para algumas ferramentas. Embora esquemas e modelos possam (e frequentemente sejam) definidos usando ferramentas convencionais e formatos de serialização como JSON e XML, para realmente adotar a MDE, seria vantajoso estar familiarizado com as ferramentas específicas utilizadas pelos profissionais da área. Devido à história da MDE, com suas raízes fortemente acadêmicas e empresariais, a Fundação Eclipse é amplamente considerada a plataforma de referência para as ferramentas de MDE mais consolidadas. No centro disso está o Eclipse Modelling Framework (EMF). Em sua essência, o projeto define uma estrutura para a definição de metamodelos e ferramentas para trabalhar com eles programaticamente em Java. Como você deve ter adivinhado, ele inclui o metametamodelo — chamado Ecore. Aqui está um diagrama simplificado dos principais Concepts e da hierarquia do Ecore:

Ecore UML simplified

É claro que há muito mais do que isso — aqui está um diagrama UML mais detalhado. Mas não se preocupe — não é algo que você precise saber. Esses são Concepts que se tornarão intuitivos ao usar o Ecore para definir seu metamodelo. É claro que há tutoriais disponíveis online sobre o EMF, embora alguns possam estar bastante desatualizados. Eles ainda são relevantes, já que o EMF está estável há muito tempo.

É possível definir metamodelos Ecore usando o editor de árvore integrado, linguagens visuais como a UML ou linguagens textuais como Emfatic, que é muito mais fácil de trabalhar do que o XML, que serve de base para todos os metamodelos Ecore. Ferramentas de nível empresarial como o Papyrus e Sirius são desenvolvidas com base no EMF e oferecem recursos mais avançados para trabalhar com modelos. Você pode até mesmo definir seu metamodelo como uma gramática para uma linguagem específica de domínio usando o Xtext.

É muita informação para assimilar! A ideia é oferecer a você uma visão geral das ferramentas e tecnologias disponíveis. Como você pode ver, as ferramentas de MDE e seus princípios são bastante abrangentes, bem estabelecidos e relativamente maduros. Você pode definir seus modelos e metamodelos graficamente ou textualmente e, como muitas ferramentas são baseadas no EMF, depois de definir seu metamodelo, você pode gerar código Java a partir dele e trabalhar com ele programaticamente, se desejar.

Gestão de Modelos

Agora que você já está familiarizado com a metamodelagem e com as ferramentas que podem ser usadas para definir (meta)modelos, talvez esteja se perguntando, com razão: e daí? O que eu posso fazer com esses modelos? Por que gastar todo esse tempo e esforço definindo um esquema que, no fim das contas, limita o que posso expressar usando uma linguagem geral? Bem, é aí que entra o verdadeiro valor do MDE. O metamodelo é necessário para que você possa trabalhar com modelos em um nível abstrato. Gerenciamento de Modelos é o processo de agir sobre os modelos. Essas tarefas incluem o seguinte:

  • Visualização: Apresentação de diferentes visões e representações gráficas de um modelo para diversos fins e públicos.

  • Consulta: Obtenção de dados do modelo, o que muitas vezes envolve expressões que exigem grande capacidade computacional.

  • Validação: Os metamodelos muitas vezes não são suficientemente poderosos para expressar todas as restrições relativas a um modelo de domínio; por isso, é necessária uma lógica programática adicional para garantir que os modelos estejam bem formados.

  • Comparação: Comparar modelos e agir com base nas diferenças de forma programática.

  • Fusão: Pegar vários modelos de entrada e produzir um único modelo de saída.

  • Migração: Mapeamento de um modelo para uma versão aprimorada do metamodelo.

  • Transformação: Modificação de um modelo ou geração de um modelo de saída diferente (que pode estar em conformidade com um metamodelo diferente).

  • Geração de texto: Uso de modelo(s) para gerar resultados textuais, como código-fonte e documentação.

Como você deve ter adivinhado, também existem ferramentas para todas essas tarefas. A linguagem de fato utilizada para validar modelos que vão além das capacidades do Ecore é a Object Constraint Language (OCL). Você pode saber mais sobre ela em um tutorial introdutório, por isso não vou me alongar nos detalhes aqui. No entanto, é útil saber que muitas outras linguagens de gerenciamento de modelos se baseiam ou são inspiradas nas expressões, sintaxe e semântica da OCL. A literatura sobre transformações de modelo para modelo é vasta e, muitas vezes, bastante complexa, já que essa é a área central de pesquisa acadêmica em MDE. Existem, é claro, linguagens para transformações de modelos, como a ATL e QVT, mas não vamos nos aprofundar nelas.

Então, como desenvolvedores, o que nós realmente importamos? Produtividade, certo? Essa é a premissa de toda a discussão. Como grande parte do nosso dia a dia é ocupada com a redação de documentação e código padrão, o que queremos é gerar automaticamente o máximo possível disso, para que possamos nos concentrar nas partes divertidas e naquelas que exigem mais atenção ou conhecimento técnico em engenharia. É aí que a transformação de modelo para texto pode ajudar. Existem padrões, como o MOF M2T , e ferramentas que os seguem, como o Acceleo, mas talvez você esteja mais familiarizado com ferramentas mais convencionais, como Jakarta Server Pages (JSP). Embora o Java na web pareça uma relíquia do início dos anos 2000, o princípio por trás dele ainda é válido. Afinal, a linguagem PHP significa literalmente “Pré-processador de Hipertexto” e ainda é amplamente utilizada. Mas o que o JSP e o PHP têm a ver com geração de código e engenharia orientada a modelos? É isso que abordaremos na parte 2 deste post. Antes disso, vamos dar uma olhada em uma ferramenta que será realmente usada para demonstrar isso.

Épsilon

Abordamos brevemente os principais Concepts do MDE e algumas ferramentas, mas como tudo isso se encaixa? Temos diferentes tecnologias de metamodelagem, de modo que os modelos podem estar em vários formatos; no entanto, a maioria das ferramentas que mencionei até agora é baseada no EMF. Além disso, como cada tarefa de gerenciamento de modelos tem sua própria ferramenta, com sintaxe e semântica variadas para definir a lógica de consulta/transformação, pode parecer que o MDE seja muito complexo e pesado, dada a curva de aprendizado íngreme. No entanto, existe um projeto (baseado no Eclipse, naturalmente) que visa unificar as diversas tecnologias de modelagem e tarefas de gerenciamento de modelos: Epsilon. Para ser totalmente sincero: contribui extensivamente para o Epsilon durante meu doutorado, então é claro que vou ser um pouco tendencioso!

Não vou me alongar explicando o Epsilon e sua arquitetura — deixarei isso para documentação, embora eu vá dar uma breve introdução. Basicamente, o Epsilon oferece uma família de linguagens de gerenciamento de modelos específicas para cada tarefa, construídas sobre uma linguagem de consulta central comum chamada EOL. Ela é inspirada na sintaxe da OCL, mas se comporta muito mais como o Java, já que é implementada em Java e faz uso intenso dos recursos de reflexão do Java. É possível até mesmo chamar código Java nativo a partir da EOL; portanto, essencialmente, a EOL é uma linguagem de programação completa, com todas as construções habituais da programação imperativa, bem como operações declarativas para trabalhar com coleções.

Um ponto crucial é que o Epsilon também oferece suporte a diversas tecnologias de modelagem e não está restrito ao EMF. Embora ofereça um suporte muito robusto a modelos EMF e se integre a outras ferramentas EMF, sua Camada de Conectividade de Modelos faz com que as linguagens sejam desacopladas do formato de persistência do modelo subjacente; assim, você pode usá-lo com vários tipos de modelos, como XML, CSV e outros formatos de planilhas, além de bancos de dados compatíveis com JDBC. Simulink e outros. Assim, o Epsilon oferece uma solução completa para gerenciamento de modelos, sem a necessidade de trabalhar com ferramentas diferentes dependendo da tecnologia de modelagem. É possível até mesmo combinar vários modelos de tipos distintos dentro do mesmo programa e trabalhar com eles de maneira uniforme.

Por enquanto é só isso...

Ufa, é muita informação para assimilar! Mas prometo que, na próxima parte, tudo vai fazer sentido por meio de um exemplo prático. Mais especificamente, vou demonstrar como usei o Epsilon para automatizar de forma eficaz a criação de uma grande parte do código padrão do SDK Java da Vonage.

Se você tiver algum comentário ou sugestão, sinta-se à vontade para entrar em contato conosco no X, anteriormente conhecido como Twitter ou dê uma passada no nosso Slack da Comunidade. Espero que este artigo tenha sido útil e agradeço quaisquer comentários ou opiniões. Se você gostou, confira meus outros artigos sobre Java.

Compartilhar:

https://a.storyblok.com/f/270183/400x400/46a3751f47/sina-madani.png
Sina MadaniEx-funcionários da Vonage

Sina é um ex-membro da equipe da Vonage. Ele atuou como Java Developer Advocate na Vonage. Com formação acadêmica, ele tem uma curiosidade geral por tudo o que se relaciona a carros, computadores, programação, tecnologia e natureza humana. Em seu tempo livre, ele gosta de caminhar ou jogar videogames competitivos.