Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Aplicando DDD de forma incremental em um projet...

Aplicando DDD de forma incremental em um projeto Django no mundo real

Na indústria de software, a expectativa de vida de ideias, metodologias e técnicas é extremamente curta. No entanto, após mais de 10 anos, DDD (Domain Driven Design) continua crescendo. Originalmente com suas raízes no paradigma orientado a objeto, o DDD é hoje apresentado e disseminado em outros paradigmas como o funcional, programação reativa, entre outros. O DDD também é aplicado em diferente estilos de arquitetura como o hexagonal e o CQRS (Command Query Responsibility Segregation).

Nesta palestra vamos falar como o uso de DDD pode beneficiar na construção de sistemas não triviais, a partir de um caso de sucesso vivenciado na ThoughtWorks. Neste projeto, a introdução do DDD, de forma gradual, transformou uma base de código com problemas típicos de times iniciantes em Python e Django - tais como excesso de lógica de negócio nas views, consultas ineficientes ao banco de dados, entre outros - em um sistema com uma arquitetura e design adequado às necessidades de um negócio com regras complexas. A aplicação desta abordagem juntamente com a aproximação do time de desenvolvimento técnico e de negócio foi fundamental para estabelecer uma relação de confiança e viabilizar a entrega de um software de qualidade.

Baseado na experiência de mais de um ano de projeto, ainda em andamento, vamos falar de forma prática e com exemplos que podem ser aplicados aos seus projetos sobre:

- Desenvolvimento ágil;

- Como evoluir sistemas de forma consistente e segura;

- Adoção de novas técnicas em times de desenvolvimento;

- Benefícios e dificuldades encontradas;

Avatar for Igor Medeiros

Igor Medeiros

June 30, 2016
Tweet

Other Decks in Programming

Transcript

  1. Projeto O que a empresa faz? Objetivos do projeto Tech

    stack Problemas com o processo inicial
  2. Domain-Driven Design "Domain-driven design (DDD) é uma abordagem de desenvolvimento

    de software para necessidades complexas conectando profundamente a implementação de um modelo evolutivo aos principais conceitos de negócio.
  3. Scenario: Atualizar o nível do plano no meio do período

    de cobrança para cliente com cartões
 Given existe uma cliente chamada "Joanna" da "California" que paga com cartão de crédito
 And um plano "Pessoal Mensal" existe e custa "R$29.00"
 And um plano "Profissional Mensal" existe e custa "R$90.00"
 And ela assina o plano "Pessoal Mensal" hoje
 When ela muda o plano para "Profissional Mensal" na metade do mês
 Then a assinatura dela é atualizada
 And a cliente deve receber uma fatura de "R$59.50"
 And a cliente deve receber uma fatura do mês seguinte de "R$90.00"
 And a conta deve ter um saldo de "R$0.00" Linguagem Ubíqua
  4. Entity class Conta(models.Model):
 """
 Representação de uma conta
 """
 id

    = models.IntegerField(
 primary_key=True,
 help_text='Identificador curto único'
 )
 name = models.CharField(
 max_length=40,
 help_text='Nome da conta'
 )
 # ...
  5. Value Objects class Pagamento(models.Model):
 conta = models.ForeignKey(
 Conta, 
 null=True,

    
 on_delete=models.CASCADE
 )
 montante = models.DecimalField(
 max_digits=9, 
 decimal_places=2
 )
 moeda = models.CharField(
 max_length=3,
 default='usd',
 choices=constants.MOEDAS,
 help_text='Código ISO para representação da moeda'
 )
 método_pagamento = models.CharField(
 max_length=20,
 default='Desconhecido'
 )
 # ...
  6. Service # sem service. View simples def perform_create(self, serializer):
 reembolso

    = serializer.save()
 
 if reembolso.conta.paga_com_cartão:
 criar_reembolso_no_stripe(reembolso)
  7. Service @transaction.atomic
 def perform_create(self, serializer):
 reembolso = serializer.save()
 
 with

    task_manager() as tm:
 conciliador = Conciliador(reembolso, task_manager=tm)
 
 if reembolso.tem_dado_de_pagamento():
 conciliador.processar_reembolso_conciliado()
 else:
 conciliador.solicitar_reembolso()
  8. Service @transaction.atomic
 def perform_update(self, serializer):
 reembolso = serializer.save()
 
 with

    task_manager() as tm:
 conciliador = Conciliador(reembolso, task_manager=tm)
 conciliador.processar_reembolso_conciliado()
  9. O que mais? policy objects task manager melhor uso do

    framework melhor OO design module (stripe sync)
  10. class PoliticaReembolsoNoCancelamento(object):
 def __init__(self, assinatura):
 self.assinatura = assinatura
 
 def

    é_reembolsável(self, quantia):
 return 2 * self.assinatura.receita_recorrente_mensal < \
 quantia <= self.assinatura.conta.quantia_reembolsável PolicyObjects
  11. Task Manager @transaction.atomic
 def perform_update(self, serializer):
 reembolso = serializer.save()
 


    with task_manager() as tm:
 conciliador = Conciliador(reembolso, task_manager=tm)
 conciliador.processar_reembolso_conciliado()
  12. Resultados Mudanças de processo scrum -> kanban estimates -> no

    estimates + confiança crescimento técnico do time pareamento novos projetos!
  13. Finalizando DDD é uma forma lidar com sistemas complexos DDD

    é sobre colocar o domínio em prioridade Não fique preso ao Django ou qualquer outro framework Pessoas > processos