O que são os Domain Services?

Domain Services são um conceito central no Domain-Driven Design (DDD), encapsulando lógica de negócios que não se encaixa em Entidades ou Value Objects. Tratam operações envolvendo múltiplas Entidades ou comportamentos específicos do domínio, promovendo um design de software coeso e organizado. São classes que contêm essa lógica de negócios, mantendo o modelo de domínio puro e evitando que Entidades e Value Objects assumam responsabilidades inadequadas.

Exemplos de Domain Services

1. Serviço de Transferência de Dinheiro

Imagine um sistema bancário onde precisamos transferir dinheiro entre duas contas. Essa operação envolve duas Entidades (Conta) e uma lógica que não pertence a nenhuma delas individualmente.

class Conta {
  constructor(public id: string, public saldo: number) {}

  debitar(valor: number) {
    if (this.saldo >= valor) {
      this.saldo -= valor;
    } else {
      throw new Error("Saldo insuficiente");
    }
  }

  creditar(valor: number) {
    this.saldo += valor;
  }
}

class TransferenciaService {
  transferir(valor: number, contaOrigem: Conta, contaDestino: Conta) {
    contaOrigem.debitar(valor);
    contaDestino.creditar(valor);
  }
}

// Uso
const conta1 = new Conta('1', 500);
const conta2 = new Conta('2', 300);

const transferenciaService = new TransferenciaService();
transferenciaService.transferir(100, conta1, conta2);

console.log(conta1.saldo); // 400
console.log(conta2.saldo); // 400

2. Serviço de Calculadora de Frete

Em um sistema de e-commerce, podemos precisar calcular o frete de um pedido. Essa lógica envolve múltiplas Entidades (Pedido, Produto, Endereco) e pode ser encapsulada em um Domain Service.

class Pedido {
  constructor(public produtos: Produto[], public endereco: Endereco) {}
}

class Produto {
  constructor(public peso: number, public dimensoes: Dimensoes) {}
}

class Dimensoes {
  constructor(public altura: number, public largura: number, public profundidade: number) {}
}

class Endereco {
  constructor(public cidade: string, public estado: string, public pais: string) {}
}

class CalculadoraFreteService {
  calcular(pedido: Pedido): number {
    let pesoTotal = pedido.produtos.reduce((total, produto) => total + produto.peso, 0);
    // Lógica simples baseada no peso total e destino
    return pesoTotal * 0.5; // Exemplo fictício de cálculo
  }
}

// Uso
const produtos = [new Produto(2, new Dimensoes(10, 10, 10)), new Produto(3, new Dimensoes(15, 15, 15))];
const endereco = new Endereco("Cidade A", "Estado B", "País C");
const pedido = new Pedido(produtos, endereco);

const calculadoraFrete = new CalculadoraFreteService();
const frete = calculadoraFrete.calcular(pedido);

console.log(`Frete: R$ ${frete}`);

Conclusão

Domain Services são essenciais para manter um modelo de domínio limpo e coeso. Eles encapsulam a lógica de negócios que não pertence a uma única Entidade ou Value Object, promovendo um design de software organizado e fácil de manter. Com esses exemplos em TypeScript, podemos ver como os Domain Services ajudam a separar preocupações e a manter a clareza do código.

Comentários

Postagens mais visitadas deste blog

Um caso de uso não deve depender de outro caso de uso

O que são Aggregates?

Repositórios não devem ser disponibilizado para os clientes