- Publicado por
Arquitetura Hexagonal Type Script
- Authors

- Name
- Gabriel Gava Pinheiro
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.
- Desacoplamento do Core Business na Arquitetura Hexagonal
- Introdução
- O que é Core Business?
- Desacoplamento do Core Business
- Benefícios do Desacoplamento
- Testabilidade na Arquitetura Hexagonal
- Desacoplamento de Componentes
- Uso de Portas e Adaptadores
- Isolamento do Core Business
- Benefícios para a Testabilidade
- Implementação de um exemplo
- Adaptabilidade a Mudanças
- Flexibilidade para Integrações
- Promove uma Estrutura Organizada
- Portas Definidas para Comunicação
- Independência de Frameworks
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.