Service: O pattern que virou anti-pattern

Alberto Luiz Souza - Jul 15 - - Dev Community

Disclaimer

Este texto foi concebido pela IA Generativa em função da transcrição do episódio do nosso canal, Dev Eficiente. O episódio completo pode ser visto no canal.

Resumo

Hoje vamos falar sobre uma sugestão de pattern que, na minha opinião, virou anti-pattern. Vou falar sobre o Service, que é descrito no livro Domain Driven Design.

A Transformação do Service em Anti-Pattern

Service é um pattern amplamente utilizado pela indústria. A grande maioria dos códigos que já revisei na Jornada Dev + Eficiente começam fazendo uso de services. Nas empresas, a galera usa service a rodo e, na minha opinião, toda a boa intenção que Eric Evans trouxe no livro foi transformada em um anti-pattern. Perdemos completamente o rumo da essência do uso da parada.

O erro que considero mais comum é desistir facilmente de enquadrar um determinado comportamento em uma entidade adequada, gradualmente chegando a um código cada vez mais procedural(só para esclarecer, não acho código procedural necessariamente pior que do OO).

Aqui eu considero uma dívida técnica pois, uma dos motivos do nascimento das linguagens orientadas a objeto, que derivam da ideia de Abstract Data Types de Barbara Liskov, é que podemos deixar funções(métodos) acessarem diretamente determinadas variáveis que são importantes para a execução delas(atributos).

Comportamento perto do estado, aumenta a coesão que, naturalmente, aumenta a testabilidade, reuso, distribuição de complexidade etc... Tudo isso sem nenhum custo adicional. Você não precisa de nenhuma lib a mais, escrever muito mais código etc. Só precisa usar uma funcionalidade pronta na linguagem.

A Essência do Service

No livro, não está escrito para você criar todo tipo de Services para tudo do seu sistema. Inicialmente é até bom relembrarmos os tipos de Services descritos por lá. Lembrando que o melhor lugar para você consultar essa informação é o próprio livro, aqui é apenas minha interpretação.

  1. Application Service - Cuida do fluxo de execução de um determinada funcionalidade. Na Arquitetura Limpa é chamado de Caso de Uso. Aqui essa comparação faz sentido, dado que estamos falando da parte tática do DDD.
  2. Domain Service - É uma abstração que deve ser criada para conter uma lógica que você julga não encaixar em nenhuma entidade específica.
  3. Infrastructure Service - Classes que oferecem serviços que não tem a ver com a aplicação em si. Por exemplo um serviço que envia emails.

O que eu mais observo é que a ideia do Domain Service é praticamente descartada(considero mais complexo enxergar oportunidades aqui mesmo) e que tudo acaba caindo nos Application Services(Casos de Uso) da vida. Inclusive as lógicas que poderiam ficar nas entidades, acabam nos casos de uso.

Aí vamos além e vemos muitas classes estilo Application Service sendo criadas que poderiam, facilmente, começar vivendo direto nos adaptadores(controllers http, listeners de fila/tópico etc) de frameworks mais modernos, que são zero intrusivos.

Exemplos Práticos

Tudo aqui é interpretação, longe de querer definir uma verdade em :).

Qual seria a responsabilidade de um Application Service ?

Imagine que temos uma funcionalidade que envolve fechar uma compra num sistema de ecommerce. Este fluxo envolve:

  1. Criar uma representação da compra.
  2. Dar baixa no estoque.
  3. Salvar no banco de dados
  4. Mandar um email para quem comprou.
  5. Gerar nota fiscal.
  6. Avisar sistema de logística.

O Application Service deve coordenar este fluxo todo. Um exemplo de código seria:

  1. Cria o objeto do tipo de compra com todos dados
  2. Realiza a alteração de estoque
  3. Salva no banco.
  4. Envia uma mensagem para um tópico para realizar as outras atividades.

E quando eu uso um Domain Service ?

Aqui eu vou me inspirar no exemplo do próprio livro, que é sobre
transferência. Só que vamos levar para o mundo dos albuns de figurinha. Isso está muito na minha mente, meu filho gosta de albuns :).

Uma funcionalidade destes sistemas é de trocar figurinhas :). O processo de troca é o seguinte:

  1. Eu te empresto minhas figurinhas e você procura por figurinhas que ainda não tem.
  2. Eu pego suas figurinhas e procuro pelas que eu não tenho.
  3. Agora a gente confere quantas figurinhas cada um(a) achou.
  4. Se tem diferença, buscamos figurinhas a mais da lista de figurinhas de quem pegou mais.
  5. Você pega as minhas e eu pego as suas.

Levando isso para código pensando em entidades ricas, estaríamos trabalhando provavelmente com duas instâncias do mesmo tipo, no caso aqui Figurinhas . As duas instâncias precisam ter seu estado alterado e, na minha visão, o melhor lugar para você realizar este fluxo é uma outra classe que toma conta do processo de alteração das duas entidades. Neste caso, poderíamos criar um Domain Service chamado TrocaFigurinhas.

A Realidade na Indústria

O que acontece na indústria é que Controller chama Application Service que faz tudo. Você tem Controller que é um CRUD. Então, Controller vai salvar um novo autor no sistema de cadastro de autores, por exemplo. Ou cadastrar um novo curso para sistemas de aulas online. Ou cadastrar um usuário novo em qualquer sistema. A pessoa faz: UsuarioController cria, UsuarioService cria, que chama UsuarioRepository cria.

Qual é realmente o motivo para isso ? Não considero que existe. Você só salvou no banco. Poderia ter salvado no banco direto do Controller.

Concluindo...

Não deixe que a ideia de Service, cuja intenção é dar mais semântica para o sistema, aproximando o código da linguagem de negócio, vire um anti-pattern na sua vida. Toda indireção tem que te dar alguma coisa em troca que vá além de argumentos básicos(futuro algo pode mudar, é um padrão para a equipe, desacopla da entrada etc).

Vamos falar mais ?

Se você gostou, deixa um comentário aqui. Tem um comentário construtivo? Deixa aqui também, com educação.

Conheça mais sobre a Jornada Dev + Eficiente

A Jornada Dev + Eficiente é um treinamento cujo propósito é fazer você entregar código em produção com cada vez mais velocidade e qualidade, de maneira cada vez mais fluída. Acreditamos que este é um caminho tende a gerar muito crescimento para sua carreira.

. . . . . . . . . . . .
Terabox Video Player