avatar
Publicado por

Arquitetura Hexagonal Type Script

Authors
  • avatar
    Name
    Gabriel Gava Pinheiro
    Twitter

Desacoplamento do Core Business na Arquitetura Hexagonal

Introdução

A arquitetura hexagonal, também conhecida como "Ports and Adapters", prioriza o desacoplamento do core business (ou domínio) de fatores externos, como bancos de dados, frameworks, interfaces de usuário e outras tecnologias. Este documento explora a importância desse desacoplamento e como ele promove a pureza e a reusabilidade da lógica de negócio.

O que é Core Business?

O core business, ou domínio, é o coração da aplicação. Ele contém a lógica de negócio essencial e as regras que definem como a empresa ou a aplicação opera. É o componente central que dita como os dados são processados, como as operações de negócio são realizadas e como as decisões são tomadas.

Desacoplamento do Core Business

Na arquitetura hexagonal, o core business é mantido isolado de fatores externos. Isso é alcançado através de:

  • Portas: São interfaces que definem os serviços que o domínio fornece ou consome.
  • Adaptadores: São implementações que conectam os serviços externos ao domínio através das portas.

Benefícios do Desacoplamento

  • Pureza do Domínio: O domínio se mantém puro e focado nas regras e lógicas de negócio, sem contaminação por detalhes de implementação externos.
  • Reusabilidade: A lógica de negócio pode ser reutilizada em diferentes contextos e aplicações, pois não está atrelada a tecnologias específicas.
  • Facilidade de Teste: A lógica de negócio pode ser testada isoladamente, sem a necessidade de interagir com elementos externos.
  • Flexibilidade: Mudanças em tecnologias externas não afetam o core business, permitindo uma adaptação e evolução mais ágeis da aplicação.

Testabilidade na Arquitetura Hexagonal

A testabilidade é uma das características mais apreciadas em sistemas de software, indicando a facilidade com que o software pode ser testado. Isso inclui a capacidade de controlar as entradas para o sistema, observar as saídas e preparar o ambiente de teste. Na arquitetura hexagonal, a testabilidade é melhorada pelas seguintes razões:

Desacoplamento de Componentes

Cada componente do sistema, especialmente o core business, é desacoplado dos outros. Isso significa que eles podem ser testados de forma independente, sem a necessidade de configurar ou depender de outros componentes do sistema.

Uso de Portas e Adaptadores

As portas definem interfaces claras para a interação com o core business. Os adaptadores permitem a substituição de componentes externos por implementações controladas e previsíveis, facilitando a criação de condições de teste específicas.

Isolamento do Core Business

O core business, sendo o coração da lógica de negócio, pode ser testado isoladamente, sem preocupações com infraestrutura, banco de dados, interfaces de rede e outras complexidades.

Benefícios para a Testabilidade

  • Testes de Unidade Facilitados: Componentes individuais podem ser testados em isolamento, reduzindo a complexidade e aumentando a velocidade dos testes.
  • Testes de Integração Mais Simples: A integração entre diferentes componentes pode ser testada usando adaptadores de teste ou mocks, sem necessidade de um ambiente completo.
  • Automatização de Testes: A clareza e a separação de preocupações promovidas pela arquitetura facilitam a automatização dos testes, tornando-os mais confiáveis e menos propensos a erros humanos.

Implementação de um exemplo

// Entidades
class Post {
  id: number
  title: string
  content: string

  constructor(id: number, title: string, content: string) {
    this.id = id
    this.title = title
    this.content = content
  }
}

Entidades que presentam o objeto, uma representção de objeto real

// Interface do Repositório
interface PostRepository {
  addPost(post: Post): void
}

// Implementação do Caso de Uso
class AddPost {
  private repository: PostRepository

  constructor(repository: PostRepository) {
    this.repository = repository
  }

  execute(post: Post) {
    this.repository.addPost(post)
  }
}

Adotamos uma interface para injetar a dependência ou seja o sistema não sabera de quem se trata apenas que a classe que herdar esse comportamento tem a função add


// Implementação do Teste
class MockPostRepository implements PostRepository {
    private addPostCalled = false;

    addPost(post: Post): void {
        this.addPostCalled = true;
    }

    wasAddPostCalled(): boolean {
        return this.addPostCalled;
    }
}

function testAddPost() {
    // Preparação
    const mockRepo = new MockPostRepository();
    const addPostUseCase = new AddPost(mockRepo);
    const newPost = new Post(1, "Test Title", "Test Content");

    // Execução
    addPostUseCase.execute(newPost);

    // Verificação
    console.assert(mockRepo.wasAddPostCalled() === true, "addPost should be called");
}

// Executando o teste
testAddPost();`

Adaptabilidade a Mudanças

Mudanças em tecnologias periféricas (como banco de dados, servidores web, frameworks) podem ser feitas com mínimo ou nenhum impacto na lógica de negócio. Isso é possível porque a comunicação com essas tecnologias é feita através de portas e adaptadores que podem ser facilmente substituídos ou modificados.

Flexibilidade para Integrações

A arquitetura permite que novas formas de interação com a aplicação (como interfaces de usuário, serviços web, etc.) sejam facilmente integradas ao sistema como novos adaptadores, sem necessidade de alterar a lógica de negócio central.

Promove uma Estrutura Organizada

A arquitetura incentiva uma organização clara do código, onde é evidente o que pertence ao domínio central e o que são detalhes de implementação específicos de plataformas ou tecnologias.

Portas Definidas para Comunicação

Todas as interações externas ocorrem através de portas bem definidas, o que ajuda a manter uma interface clara e controlada para comunicação com o domínio da aplicação.

Independência de Frameworks

A aplicação não fica atrelada a um framework específico, permitindo a liberdade de escolher, alterar ou atualizar frameworks sem grandes impactos na lógica de negócio.