Migrando sistemas monoliticos para microsserviços com Domain Driven Design.

Marcos Vinicios da Silveira
20 min readFeb 5, 2023

--

Este post tem como objetivo exemplificar a migração de um sistema monolítico, utilizando o padrão Strangler Fig, Design Orientado a Domínios para modelagem do sistema e o padrão Arquitetura Hexagonal para a estruturação dos microsserviços

Não entraremos em profundidade em todos os padrões neste post.

Introdução

A migração de um sistema monolítico para uma arquitetura baseada em microserviços pode ser um desafio. Para facilitar este processo, é possível utilizar o padrão Strangler Fig, que consiste em substituir gradualmente partes do sistema antigo por serviços independentes e conectados. Além disso, a modelagem do sistema baseada no Domain Driven Design ajuda a identificar os domínios de negócio relevantes e a estruturar os serviços de acordo. Por fim, a aplicação do padrão Hexagonal Architecture permite que o sistema seja composto por serviços que possuam uma camada interna independente, o que facilita o gerenciamento e a manutenção dos serviços. Desta forma, é possível obter uma arquitetura escalável e de fácil manutenção, além de melhorar a qualidade do código.

Sobre a migração

Para que uma migração para microsserviços seja bem-sucedida, é importante ter um objetivo claro. Não ganhamos com a existência de um microsserviço, ganhamos com uma decisão coerente, tomada de forma racional, com foco nos objetivos do negócio. Deve-se pensar em migrar para uma arquitetura de microsserviços com o propósito de solucionar problemas que o sistema atual não é capaz de resolver. É importante também avaliar a escalabilidade da arquitetura em relação ao negócio e sua capacidade de atender as demandas a médio e longo prazo. As regras de negócio devem ser a base para a existência do software e, por isso, devem ser consistentes.

Oque podemos alcançar com microsserviços?

A resposta deve ser uma série de resultados alinhados aos objetivos de negócio e deve ser comunicada de forma clara, descrevendo as vantagens que os usuários finais do sistema irão obter. Ao optar por microsserviços, é possível estabelecer metas para a empresa, aumentar a autonomia das equipes, realizar e implementar mudanças em microsserviços individualmente, escalar para lidar com a carga de forma viável e incorporar novas tecnologias.

Começando com DDD

Como dito antes não é o objetivo desta publicação abordar todas terminologias e propostas usadas no DDD. Mas é necessário entender algumas coisas para prosseguir-mos.

O Design Orientado a Domínios é uma coleção de ideias, princípios e padrões que auxiliam na concepção de sistemas de software baseados no modelo subjacente do domínio de negócios. O DDD possui dois ambientes distintos, o espaço do problema e o espaço da solução.

Basicamente com o DDD desenvolvemos modelos nos contextos delimitados. E para isso temos algumas terminologias a serem entendidas;

  • Domínio : Um domínio no sentido amplo, é oque a organização faz e o modo que ela cria algo. Um domínio pode ser referir tanto a totalidade de um domínio de negócio tanto apenas a uma área basicamente ou ao suporte dela.
  • Subdomínio: Os subdomínios abrangem as demais regras de negócio ou modelos que não fazem parte do Domínio.
  • Contexto Delimitado : Um contexto delimitado é um limite explicito dentro do qual um modelo de domínio existe. O modelo de domínio expressa uma linguagem onipresente como um modelo de software.
  • Linguagem Onipresente: Uma linguagem onipresente é um vocabulário compartilhado por todos os envolvidos em um projeto, de especialistas de domínio e as partes interessadas com objetivo de reduzir a ambigüidade da comunicação.
  • Entidade: Uma entidade é um algo único que possuí uma continuidade em seu ciclo de vida e pode ser distinguida independente dos atributos que são importantes para aplicação do usuário. Entidade é identidade, é algo único que pode ser alterado de forma continua.
  • Objeto de Valor: Quando você se preocupa apenas com atributos de um elemento de um modelo, classifique isso como um objeto de valor.
    “Trate o Objeto de Valor como imutável” — Eric Evans.
  • Agregado: Um agregado é um conjunto de objetos associados que tratamos como uma unidade para o propósito de mudança de dados. Um agregado pode ser um conjunto de entidades e objetos de valor que fazem sentido juntos, principalmente quando se trata a mudança.
  • Evento de Domínio: Um evento é algo que aconteceu no passado. Um evento de domínio é algo que aconteceu no domínio que você deseja que outras partes do mesmo domínio (em processo) saibam. As partes notificadas geralmente reagem de alguma forma aos eventos. Basicamente falando o evento de domínio expressa um estado de um agregado.

Por onde começamos a migração?

Para aplicar o DDD ao nosso cenário de migração, envolveria o seguinte fluxo de trabalho:

  1. Identificamos uma fatia de nosso sistema monolítico para realizar a migração. Criaremos um cenário para isso.
  2. Começamos analisando de forma pragmática e representativa nosso sistema monolítico, com intuito de descrever uma zona problemática. O Big Ball of Mud pode ser uma técnica simples e eficaz para especificar a confusão.
  3. Analise os casos de uso de negócios do mundo real para descobrir o domínio e os subdomínios no espaço do problema. Normalmente, o Event Storming é uma ferramenta eficaz para dar suporte a isso.
  4. Defina o contexto delimitado no espaço da solução
  5. Dentro de um contexto delimitado, aplique o padrão DDD tático para definir entidades, agregados, serviços de domínio, eventos de domínio e etc.
  6. Use os resultados da etapa 5 para identificar os microsserviços.
  7. Defina um padrão para sua migração. No nosso caso estaremos abordando o padrão Strangler Fig.

Oque não devemos fazer em uma migração

“Quando enfrentamos uma situação de migração devido ao acoplamento excessivo, é comum pensarmos que o desafio reside na mistura das camadas de regras de negócios, infraestrutura e framework. Nesse caso, a primeira ideia é desacoplar essas camadas criando um serviço separado do sistema monolítico, utilizando os mesmos conceitos, regras e infraestrutura, e chamá-lo de microsserviço. No entanto, ao projetar interfaces distribuídas para software existente, as interfaces precisam ser redesenhadas e é necessário considerar um modelo de objeto separado e de maior granularidade para as interfaces distribuídas. Se ignorarmos isso, estamos entrando no anti-padrão de arquitetura de software conhecido como Autogenerated Stovepipe.

Criando o nosso cenário monolítico

Para darmos mais vida a este plano, vamos criar um cenário fictício de um sistema monolítico.

Cenário

Imagine uma startup de e-commerce, chamada FashionShop, que está começando a operar. Eles precisam de um sistema que permita aos clientes comprar roupas on-line e acompanhar o status de suas compras. A equipe de desenvolvimento da FashionShop optou por utilizar o framework Django para desenvolver o sistema, pois é fácil de aprender e possui uma ampla gama de recursos prontos para uso, como gerenciamento de usuários, gerenciamento de pedidos e pagamentos.

A FashionShop decidiu utilizar uma arquitetura monolítica para o sistema, pois a equipe é pequena e tem pouca experiência em arquitetura de software. Além disso, o sistema é relativamente simples e não requer muitos recursos avançados, como escalabilidade e tolerância a falhas. A arquitetura monolítica permite que a equipe implemente e teste rapidamente novas funcionalidades, o que é importante para a startup, que precisa se estabelecer no mercado o mais rápido possível.

A equipe de desenvolvimento da FashionShop escolheu o Django porque ele é conhecido por ser fácil de usar e por possuir uma ampla gama de recursos prontos para uso, como gerenciamento de usuários, gerenciamento de pedidos e pagamentos. Além disso, o Django é uma plataforma popular e bem documentada, o que significa que a equipe pode encontrar facilmente ajuda e soluções para problemas que possam surgir ao longo do desenvolvimento do sistema.

Em resumo, a FashionShop optou por utilizar uma arquitetura monolítica no Django devido à simplicidade e rapidez de desenvolvimento que oferece, bem como à ampla gama de recursos prontos para uso e à popularidade e documentação da plataforma.

Com o passar do tempo, a FashionShop pode encontrar alguns desafios com sua arquitetura monolítica, especialmente se o sistema estiver com altos níveis de dependências. Alguns dos problemas que podem surgir incluem:

  1. Dificuldade de manutenção: a medida que o sistema cresce em tamanho e complexidade, pode se tornar difícil manter e corrigir erros. A dependência de muitos componentes do sistema pode tornar a manutenção do código complexa e demorada.
  2. Dificuldade de escalabilidade: a arquitetura monolítica pode tornar-se uma limitação à medida que a FashionShop precisar escalar o sistema para atender a crescente demanda. A dependência de muitos componentes do sistema pode tornar a escalabilidade difícil e cara.
  3. Dificuldade de implantação: ao fazer atualizações ou correções em uma arquitetura monolítica, a FashionShop pode precisar implodir o sistema inteiro, o que pode levar a interrupções no serviço e aumentar o tempo de inatividade.
  4. Dificuldade de teste: devido à dependência de muitos componentes do sistema, testar uma nova funcionalidade ou correção pode ser demorado e complexo.

Impactos no Negócio

Os problemas relacionados a uma arquitetura monolítica, como a FashionShop, podem ter impactos significativos no negócio, incluindo:

  1. Demora no tempo de mercado: se o sistema é difícil de manter ou escalar, isso pode atrasar o lançamento de novas funcionalidades ou correções importantes, afetando o tempo de mercado da FashionShop.
  2. Interrupções no serviço: se o sistema é difícil de atualizar ou implodir, isso pode resultar em interrupções no serviço e aumento do tempo de inatividade.
  3. Satisfação do cliente prejudicada: se o sistema está com problemas, isso pode prejudicar a satisfação do cliente e prejudicar a reputação da FashionShop.
  4. Aumento de custos: se o sistema é difícil de escalar ou manter, isso pode aumentar os custos da FashionShop, como o aumento da equipe de desenvolvimento ou a necessidade de adquirir soluções externas.
  5. Dificuldade de competir: se a FashionShop estiver atrasada em relação aos concorrentes em lançar novas funcionalidades ou correções importantes, isso pode prejudicar a capacidade da empresa de competir no mercado.

Estrutura

Considerando os aspectos, nosso aplicativo monolítico é construído como única unidade unificada, e supomos a falta de algumas representações como Produto e Catalogo, e esta ausência está concentrando regras excessivas na nosso pacote de Pedido em nosso aplicativo Django.

Especificando a confusão

Iremos utilizar uma técnica simples aplicada no DDD, o Big Ball of Mud (Grande bola de lama), que introduz uma selva de código estruturada ao acaso, extensa, desleixada e conectada por fitas.

O termo “Big Ball of Mud” no contexto de Domain-Driven Design (DDD) se refere a uma arquitetura de software mal projetada ou não estruturada. É uma metáfora para descrever uma aplicação que cresceu descontroladamente, sem uma estrutura clara e coerente, tornando-se difícil de manter, evoluir e escalar. O objetivo do DDD é ajudar a evitar ou corrigir esse tipo de arquitetura, fornecendo práticas e princípios para projetar sistemas de software de maneira estruturada e baseada em modelos de negócio relevantes.

Normalmente esse problema aparece em arquiteturas onde falta pontos de percepção e são cenários de acoplamento caóticos.

Como funciona ?

Na especificação é desenhado um limite em torno de toda a confusão, que que ira especificar a nós uma Grande Bola de Lama. Neste momento não aplicamos nenhuma modelagem sofisticada para o contexto.

Exemplo Ilustrativo.

Está técnica é útil, pois permite-nos olhar para o sistema legado, sugerindo desenharmos um limite em torno da confusão, para que assim possamos especificar a Grande Bola de Lama. Essa apenas servira como um indicador de tendências desses sistemas de se expandirem para outros contextos, além de facilitar na descoberta dos domínios e subdomínios existente em nosso sistema monolítico.

No espaço da confusão, definimos a estrutura em larga escala do sistema sem padrões estratégicos, que se concentram apenas na análise do domínio e em sua linguagem ubíqua.

Desenhando um mapa de contexto

Um mapa de contexto ira capturar o terreno existente. Primeiro, devemos sempre mapear o presente e não o futuro imaginado. Se o cenário mudar à medida que o projeto atual avança, podemos atualizar o mapa nesse momento. Primeiro focalizamos a situação atual de modo que possamos formar uma compreensão de onde estamos e determinar para onde queremos ir em seguida.

Neste momento é que buscamos desenhar um mapa de contexto combinando os objetivos de negócio e de implementação de recursos do sistema.

Entendendo os domínios

Lembrando.. Um domínio é o que a empresa faz e o contexto de como ela faz isso.

Em nossa especificação de Big Ball of Mud do Domain Driven Design, podemos identificar os domínios de Order, Product, Delivery, Maps e Payment. Que poderiam ser representados como círculos separados, com setas mostrando as relações e interações entre eles. Por exemplo:

  • O domínio de Order poderia ser representado como um círculo central, pois é o ponto central do sistema, tendo relações com os outros domínios.
  • O domínio de Product pode estar conectado ao domínio de Order, pois os pedidos são feitos com base nos produtos disponíveis.
  • O domínio de Delivery pode estar conectado ao domínio de Order e ao domínio de Maps, pois é responsável por entregar os pedidos e precisa conhecer a localização dos clientes.
  • O domínio de Maps pode estar conectado ao domínio de Delivery e ao domínio de Payment, pois precisa fornecer informações de localização e cobrar pelos serviços de entrega.
  • O domínio de Payment pode estar conectado ao domínio de Order, pois é responsável por processar as transações financeiras dos clientes.

Essa é apenas uma possível estruturação do diagrama, e pode variar de acordo com as especificidades do sistema. O objetivo é representar de forma clara e visual a interação e dependência entre os domínios.

Importância da migração gradual

É importante lembrar que estamos realizando uma migração, e que devemos ter um conjunto de resultados alinhado aos objetivos do negócio.

“Se você fizer uma reescrita Big Bang, á única coisa que poderá garantir é que terá um Big Bang”

Espaço do problema

Com intuito de realizar-mos entregas graduais, iremos trabalhar por contextos. E o contexto escolhido foi o de Pedidos ..

Domínio: e-commerce

Oferecer uma plataforma para venda de produtos ou serviços pela internet, visando atrair clientes e aumentar suas receitas.

Subdomínios:

  • Order: Este domínio é responsável por gerenciar e processar pedidos feitos pelos clientes, incluindo a seleção de produtos, cálculo de preços e finalização do pagamento.
  • Product: Este domínio é responsável por gerenciar e fornecer informações sobre os produtos disponíveis para venda, incluindo descrições, preços e imagens.
  • Delivery: Este domínio é responsável por gerenciar e rastrear entregas, incluindo a programação de entregas, o acompanhamento da localização do transportador e o processamento de devoluções.
  • Maps: Este domínio é responsável por fornecer informações geográficas, incluindo rotas de entrega, locais de entrega e tempo estimado de viagem.
  • Payment: Este domínio é responsável por processar pagamentos, incluindo autorizações de cartão de crédito, verificações de saldo e confirmações de pagamento

Linguagem Onipresente

A Linguagem Ubíqua (ou Linguagem Onipresente) é um conceito central de DDD. Ela consiste de um conjunto de termos que devem ser plenamente entendidos tanto por especialistas no domínio (usuários do sistema) como por desenvolvedores (implementadores do sistema).

Imaginando que realizamos uma discussão com os especialistas do domínio, a seguinte linguagem onipresente é aceita em todas as equipes:

A seguir está a Linguagem Ubíqua para o nosso mapa de contexto , incluindo os domínios de Order, Product, Delivery, Maps e Payment:

Order:

  • Pedido: Representa uma solicitação de compra feita pelo cliente.
  • Item de Pedido: Representa um item específico incluído em um pedido.
  • Status do Pedido: Representa o estado atual de um pedido, como “em processamento”, “pago” ou “cancelado”.

Product:

  • Produto: Representa um item vendido pela empresa.

Delivery:

  • Entrega: Representa o processo de transporte de um pedido até o destinatário.
  • Endereço de Entrega: Representa o local onde um pedido deve ser entregue.

Maps:

  • Mapa: Representa uma representação visual de uma área geográfica.
  • Localização: Representa um ponto específico no mapa.
  • Rota: Representa uma série de pontos que representam o caminho entre duas localizações.

Payment:

  • Pagamento: Representa o processo de pagamento por um pedido.

Espaço de solução

  • Contexto delimitado: Gerenciamento de Pedidos

Um contexto delimitado (BC) delimita o escopo de um modelo de domínio. A partir do resultado da análise do espaço do problema, podemos definir os seguintes contextos limitados:

Domínios:

  1. Order: Este domínio é responsável por gerenciar as compras feitas pelos clientes na loja virtual. Ele inclui a criação de pedidos, a seleção de produtos, a definição de endereços de entrega e pagamento, além da gestão de informações sobre o status do pedido.
  2. Product: Este domínio é responsável por gerenciar as informações sobre os produtos disponíveis para venda na loja virtual. Isso inclui a descrição dos produtos, fotos, preços, estoque, categorias e outras informações relevantes.
  3. Delivery: Este domínio é responsável por gerenciar as entregas dos pedidos realizados na loja virtual. Isso inclui a seleção de transportadoras, a definição de rotas, a gestão de informações sobre a entrega e a interação com os clientes.
  4. Maps: Fornece suporte ao sistema de entrega, fornecendo informações de rotas e localização.
  5. Payment: Este domínio é responsável por gerenciar as informações relacionadas a pagamentos dos pedidos realizados na loja virtual. Isso inclui a integração com gateways de pagamento, a validação de informações de cartão de crédito, a gestão de cobranças e outros aspectos relacionados a pagamentos.

Esses contextos delimitados estão no relacionamento upstream-downstream (mais especificamente: cliente-fornecedor), onde por exemplo Order(downstream) depende Catalogapenas da API do (upstream).

Dentro de nosso domínio principal, podemos encontrar outros contextos delimitados, como Catalog, Inventory, Delivery e Product. Porém estes contextos não serão abordados na nossa dinâmica, já que estamos abordando o tema de uma migração.

Analisando os casos de uso do negócio.

A partir do cenário e da linguagem onipresente que analisamos anteriormente, podemos identificar os seguintes eventos agregados, entidades, objeto de valor e domínios.

Isso pode ser feito por meio de um Event Storming.

Exemplo do nosso Event Storming para o nosso Contexto Delimitado de Ordering:

  • Novo pedido criado: Um evento que representa a criação de um novo pedido pelo cliente.
  • Item adicionado ao pedido: Um evento que representa a adição de um item a um pedido existente.
  • Pedido pago: Um evento que representa o pagamento bem-sucedido de um pedido.
  • Pedido cancelado: Um evento que representa o cancelamento de um pedido.

Aplicando DDD tático.

Após definição do contexto limitado e o cenário da linguagem onipresente, podemos então aplicar o DDD Tático para descrever e definir nossos eventos agregados, entidades, objetos de valor, eventos de domínio e o próprio domínio.

Modelo de domínio

O modelo de domínio é principalmente um modelo de programação de software aplicado a um subdomínio específico. Que define o vocabulário e atua como uma ferramenta de comunicação para todos os envolvidos (negócios e TI), originando uma Linguagem Ubíqua . Nos próximos tópicos irei abordar nosso modelo de programação, com código fonte disponibilizado no GitHub.

Arquitetura Hexagonal

A solução para este projeto será baseada no Padrão de Arquitetura Hexagonal, também conhecido como Arquitetura de Núcleo, Port-Adapter. Este padrão permite a separação da lógica de negócios da aplicação da lógica de apresentação e persistência de dados, permitindo a criação de uma camada de aplicação isolada que pode ser facilmente testada e mantida.

Como funciona a estrutura de uma arquitetura hexagonal?

No padrão o aplicativo é visto como um hexágono, com cada lado representando uma interface que pode ser implementada de maneiras diferentes. As interfaces são chamadas de “ports” e as implementações são chamadas de “adapters”.

A ideia principal por trás da arquitetura hexagonal é que o núcleo lógico do aplicativo (hexágono central) não dependa diretamente de tecnologias externas ou infraestruturas, como banco de dados ou sistemas de mensagens. Em vez disso, ele se comunica com o mundo exterior através das interfaces (ports) que são implementadas pelos adapters.

Dessa forma, o núcleo do aplicativo fica isolado das mudanças tecnológicas e é mais fácil de testar, manter e evoluir. Além disso, novos adapters podem ser adicionados ou substituídos sem afetar o núcleo do aplicativo.

Funcionamento da estrutura de pastas

A estrutura de pastas de uma arquitetura hexagonal depende muito da implementação, mas geralmente é baseada no princípio de separação de preocupações. Aqui está um exemplo comum de estrutura de pastas para uma arquitetura hexagonal:

  • domain: Contém as entidades, serviços e regras de negócio do aplicativo. Este é o núcleo lógico da aplicativo e deve ser independente de tecnologias externas.
  • application: Contém as implementações dos serviços de aplicação que são responsáveis por orquestrar a execução das regras de negócio.
  • adapters: Contém as implementações dos adapters, incluindo acesso a banco de dados, integração com sistemas externos, envio de e-mails, etc.
  • ports: Contém as definições das interfaces (ports) que são usadas para comunicação entre o núcleo lógico do aplicativo e o mundo exterior.
  • tests: Contém os testes unitários e de integração que cobrem o código do aplicativo.

Esta estrutura de pastas é apenas um exemplo, e outras variações podem ser aplicadas dependendo das necessidades específicas de cada projeto. O importante é que a estrutura de pastas ajude a manter a separação de preocupações e facilite o desenvolvimento, teste e manutenção do aplicativo.

Adapters

Adapters na arquitetura hexagonal dita como será a comunicação do serviço com mundo externo ou como o mundo externo se comunica com nosso serviço.

No fonte abaixo exemplifico nosso Adaptador REST , que possuí componentes que fornecem uma camada de adaptação entre a camada interna da aplicação (onde as regras de negócio são implementadas) e as camadas externas da aplicação (onde o sistema interage com o mundo exterior, como bancos de dados, serviços web, interfaces do usuário, etc.).

Neste exemplo permitimos que a camada interna da aplicação seja isolada das tecnologias externas e, assim, facilita a manutenção e evolução da aplicação.

Ports

Na arquitetura hexagonal, os “ports” são interfaces que representam os pontos de entrada e saída da aplicação, permitindo que ela se conecte a outros sistemas externos como bancos de dados, serviços de terceiros, entre outros. Eles definem a forma como a aplicação se comunica com o mundo exterior e são implementados por adaptadores que traduzem as chamadas para o formato exigido pelo sistema externo.

Por exemplo, em nosso domínio de Pedido possuímos 2 interfaces, uma para nosso repository.

E outra para o nossa camada de aplicação.

Controller

Em uma arquitetura hexagonal, o papel de um controller é intermediar a comunicação entre a camada de apresentação (interface do usuário) e a camada de negócios (domínio), garantindo que as solicitações do usuário sejam traduzidas em ações do sistema e que os resultados sejam apresentados de forma adequada na interface.

O controller também pode realizar tarefas de validação de entrada e gerenciamento de erros.

Repository

No contexto da arquitetura hexagonal, o repositório é uma camada que funciona como intermediário entre o domínio e o armazenamento de dados. Ele tem como objetivo isolar o acesso aos dados de negócio e garantir a persistência dos dados, sem que o domínio precise conhecer as detalhes da implementação de armazenamento. O repositório implementa uma interface que define as operações básicas de CRUD e é utilizado pelo domínio para obter e salvar os dados, garantindo a independência e flexibilidade da aplicação.

Application

Na arquitetura hexagonal, a camada de aplicação é o centro do sistema e é responsável por gerenciar as regras de negócios e as interações com os usuários. É composta por objetos de domínio que representam os conceitos do mundo real e realizam as operações necessárias para cumprir as necessidades do usuário.

Normalmente acamada de aplicação é isolada das tecnologias externas através do uso de contratos ou interfaces, o que permite a substituição ou atualização de adaptadores sem afetar a lógica de negócios do sistema. Dessa forma, a camada de aplicação é independente das tecnologias subjacentes e é livre para se concentrar na implementação de suas regras de negócios.

Você pode acessar a solução completa no GitHub por aqui.

Agora que já conhecemos nosso microsserviço, podemos partir para executar a migração da nossa fatia do sistema.

Migrando com o padrão Strangler Fig

O padrão de migração "Strangler Fig" consiste em gradualmente substituir partes de uma aplicação antiga (a “árvore”) com uma nova aplicação (a “figueira”) ao redor dela, sem interromper o funcionamento da aplicação antiga. Isso é feito inserindo uma camada intermediária que direciona as requisições da aplicação antiga para a nova aplicação, permitindo que as partes da aplicação antiga sejam gradualmente migradas e substituídas pela nova aplicação. O objetivo é fornecer uma maneira segura e controlada de migrar de uma aplicação antiga para uma nova, sem interromper o funcionamento da aplicação antiga e permitindo aos desenvolvedores validar e testar a nova aplicação antes de torná-la totalmente responsável pela funcionalidade da aplicação.

Para implementar o padrão Strangler fig, dependemos de três passos, que estão representados nas imagens abaixo. Primeiramente é necessário identificar as partes do sistema atual na qual desejamos migrar . Em seguida, é necessário implementar a funcionalidade em um novo microsserviço. O ultimo passo é desviar as chamadas do sistema monolítico para o novo microsserviço.

(Visão geral do padrão Strangler Fig)

Ocasionalmente, podemos extrair uma porção completa, fim a fim, da funcionalidade como vemos na imagem abaixo.

Em nosso caso, será necessário trabalhar com fatias menores, teremos de considerar extrações rasas, para que as mesmas possam ser normalizadas e aplicadas em nossa nova arquitetura, seguindo conceitos aplicados no Domain Driven Design.

Benefícios da nossa migração utilizando Strangler Fig + DDD

A adoção do Domain-Driven Design (DDD) pode oferecer vários benefícios para o desenvolvimento de software, incluindo:

  1. Maior clareza do negócio: DDD ajuda a traduzir conceitos do negócio em modelos de software bem definidos, resultando em uma melhor compreensão das necessidades e requisitos do negócio.
  2. Maior qualidade do código: DDD incentiva a criação de soluções de software claras, coesas e coerentes, o que ajuda a melhorar a qualidade e a manutenibilidade do código.
  3. Melhor colaboração entre equipes: DDD facilita a comunicação entre equipes de desenvolvimento de software e de negócios, promovendo uma colaboração mais efetiva e resultados mais alinhados aos objetivos do negócio.
  4. Maior escalabilidade: DDD ajuda a construir soluções de software escaláveis, pois incentiva a separação de responsabilidades e a definição de modelos claros e coerentes.
  5. Flexibilidade para mudanças: DDD ajuda a lidar com mudanças no negócio, permitindo a adaptação do software de forma mais rápida e eficiente, sem comprometer a qualidade e a integridade do sistema.

A migração utilizando o padrão "Strangler Fig" pode oferecer os seguintes benefícios:

  1. Incrementalidade: A migração em etapas permite a adoção gradual de novas tecnologias e soluções, sem o risco de interrupções ou falhas em sistemas críticos.
  2. Redução de risco: Ao implementar mudanças em partes menores do sistema, o risco é distribuído e a probabilidade de falhas é reduzida.
  3. Melhoria contínua: A migração incremental permite a melhoria contínua do sistema, com a implantação de soluções mais modernas e eficientes ao longo do tempo.
  4. Maior flexibilidade: O padrão Strangler Fig permite a adaptação às mudanças no negócio, sem a necessidade de uma grande reestruturação do sistema.
  5. Menor impacto no negócio: A migração incremental minimiza o impacto no negócio e nas operações, permitindo que o sistema continue a funcionar normalmente durante a transição.
  6. Gerenciamento de mudanças: A migração incremental permite que as mudanças sejam gerenciadas de forma mais eficiente, com um controle mais preciso sobre o processo e os resultados.
  7. Comunicação efetiva: O padrão Strangler Fig incentiva a comunicação efetiva entre equipes, incluindo desenvolvedores, gerentes de negócios e stakeholders, aumentando a colaboração e a eficiência da equipe.

Desafios e Lições

Ao utilizar o Domain-Driven Design (DDD), é importante estar ciente dos seguintes desafios e lições:

  1. Aprendizado contínuo: DDD é uma abordagem complexa e requer tempo e dedicação para ser compreendido e aplicado corretamente. É importante estar disposto a aprender continuamente e a evoluir a sua compreensão do DDD.
  2. Alinhamento com o negócio: É fundamental garantir que o DDD esteja alinhado com as necessidades do negócio e não se torne um objetivo em si mesmo. É preciso equilibrar a aplicação rigorosa do DDD com a flexibilidade necessária para atender às demandas do negócio.
  3. Envolvimento da equipe: DDD é uma abordagem que requer envolvimento e colaboração de toda a equipe, incluindo desenvolvedores, gerentes de negócios e stakeholders. É importante garantir que todas as partes estejam envolvidas e comprometidas com o sucesso da aplicação do DDD.
  4. Evolução contínua do modelo: O modelo de domínio é um elemento dinâmico e está sujeito a mudanças conforme o negócio evolui. É importante garantir que o modelo seja revisado e atualizado regularmente para refletir as mudanças no negócio.
  5. Foco no valor: DDD incentiva o foco no valor para o negócio e é importante garantir que as soluções de software sejam desenvolvidas com esse objetivo em mente. É preciso equilibrar a complexidade técnica com a simplicidade necessária para entregar valor efetivo ao negócio.

Alguns desafios comuns ao usar o padrão Strangler Fig em uma migração de sistemas monolíticos incluem:

  1. Integração com sistemas existentes: Integrar o novo sistema com os sistemas legados pode ser desafiador, especialmente se eles têm diferentes arquiteturas e tecnologias.
  2. Testes: É importante ter uma boa cobertura de testes para garantir a qualidade do sistema a medida que ele é reescrito.
  3. Comunicação e colaboração: É crucial envolver todas as equipes relevantes (desenvolvimento, operações, negócios, etc.) durante o processo de migração.

Algumas lições importantes incluem:

  1. Planejamento: Planejar cuidadosamente o processo de migração, incluindo o que será migrado e quando, ajudará a garantir o sucesso.
  2. Pequenas etapas: Ao invés de tentar migrar tudo de uma só vez, é melhor dividir o processo em pequenas etapas gerenciáveis.
  3. Monitoramento: É importante monitorar o desempenho do sistema durante e após a migração para identificar e corrigir problemas rapidamente.
  4. Flexibilidade: Estar preparado para mudanças e flexibilidade durante o processo de migração é importante, já que pode ser necessário ajustar o plano à medida que as coisas evoluem.

Conclusão

Em conclusão, o Domain-Driven Design (DDD) é uma abordagem poderosa para o desenvolvimento de software que pode oferecer muitos benefícios, incluindo maior clareza do negócio, qualidade do código, colaboração efetiva entre equipes, escalabilidade e flexibilidade para mudanças. No entanto, é importante estar ciente dos desafios que acompanham a adoção do DDD, incluindo a necessidade de aprendizado contínuo, alinhamento com o negócio, envolvimento da equipe, evolução contínua do modelo e foco no valor. Para obter sucesso com o DDD, é preciso equilibrar rigor e flexibilidade, alinhar o modelo com as necessidades do negócio e envolver todas as partes interessadas na colaboração e na entrega de valor efetivo.

References

--

--