Olá pessoal, Hoje vamos falar sobre DDD, TDD, BDD.
Muitas vezes pela internet em busca de novos conhecimentos nos deparamos com diversas siglas, estando elas anunciadas em algum requisito para desenvolvimento de sistema ou até mesmo citadas em alguma abordagem técnica.
Afinal o que são e para que servem?
Abordaremos de forma prática sua definição, muitos irão perceber que já estão usando e nem sabiam.
DDD – Domain-Driven Design (Desenvolvimento Guiado por Design ou Desenvolvimento orientado a Domínio)
Erick Evans lançou em 2003 o “Domain-Driven Design: Tackling Complexity in the Heart of Software” Mal imaginou que o livro tanto quanto o conceito alcançaria tal sucesso e respeito.
Trata-se de uma abordagem de design de software de forma disciplinada, abordando uma série de conceitos e técnicas sempre com foco no domínio do software.
Hoje em dia precisamos entender muitas técnicas, OO, SOA, EntityFramework, NHibernate, Injeção de Dependência e etc… O DDD não vem para substituir e também não é uma tecnologia, poderíamos dizer uma filosofia, não é algo super novo inventado e sim mais uma compilação de muito que já sabemos e aplicamos.
Como dito anteriormente o foco é no Domínio do Software, no propósito que o software deve atender, é a automatização de um processo de negócio.
Domínio nada mais é que do que você já está imaginando, ou seja, atender completamente um determinado negócio.
Ok! Mas todos os softwares corporativos não são desenvolvidos nesse propósito?
O DDD traz abordagens de como fazer isto, como atender um domínio complexo de informações. O pilar do DDD é conceitualizar em forma de Modelo o seu domínio.
Quando pensamos em modelo nos vem à cabeça: UML, Diagrama de Sequência, Diagrama de Estados e todo arsenal que pudermos montar.
Mas não exatamente, o Modelo pode ser feito de qualquer forma que possa ser entendido, Papel de pão, UML, Lego ou Massa de modelar, Não há padrão para modelo. Se o seu modelo expressar certo o funcionamento de negócio está perfeito!
E o que aborda o Modelo?
O modelo é um universo composto por cinco itens principais:
Entidades, Objetos de Valor, Factories, Serviços, Repositórios.
Já começou a ficar familiar, mas vamos entender mais um detalhe que o DDD aborda:
Ubiquitous Language:
Traduzindo, “Linguagem Onipresente”, é a que está em todo lugar. É a linguagem de quem entende do negócio.
Ex. O seu cliente, por um acaso um banco, fala Amortização (pagamento de parcelas). Logo sua equipe também fala Amortização, e isso se repete no modelo e no código.
É uma forma de todos falarem a mesma língua, a língua do negócio (Domínio).
Para se obter sucesso de um projeto DDD é necessário que todos os integrantes falem e entendam completamente o domínio.
Separação das camadas:
Na hora de desenvolver as camadas é necessário cuidado, as camadas precisam ser independentes, se duas camadas se misturam então não são duas camadas. Se você está desenvolvendo um sistema Web orientado a um domínio e resolveu migrar para ASP.Net, você necessita mudar a camada de UI (User Interface) e nada mais, pois são camadas independentes, o Core Domain (Dominio Principal) não depende da camada UI, e não só necessariamente uma UI, podemos estar falando de um WebService por exemplo, imagine que esta desenvolvendo um serviço SOA e quem consome o Core Domain seja um outro sistema.
Um software de negócios, com regras complexas pode ter N camadas, mas deve existir a camada Domínio, ela é o coração do sistema e a mais importante, afinal lá estão as regras de negócio que atendem ao domínio.
Voltando aos itens principais do modelo, começaremos com a Entidade:
Tudo que tenha valor ao domínio (regra de negócio) deve possuir uma entidade.
Voltando ao exemplo do banco, uma entidade seria o Cliente, toda entidade possui uma identidade nesse caso a Entidade Cliente possui uma Identidade (CPF).
Devemos escrever nesta camada todas as entidades ligadas ao domínio da forma mais simples, que seja implementada facilmente sem algum tipo de interface ou etc.
Objetos de valor:
São objetos reconhecidos por seus atributos e geralmente são imutáveis.
Por ex: Tipos de Conta são do tipo Corrente, Investimento, Crédito, Transitória e etc.
Sendo assim na hora de referenciar esse objeto de valor em sua entidade você necessita que ele possua estes tais atributos, pois fazem parte do domínio de seu negócio, chamamos isso de Agregação.
Serviços:
São ferramentas, pois não são entidades nem possuem objetos de valor.
Se por exemplo você precisa enviar um relatório de contas correntes ao Banco Central, sua entidade bem como os objetos de valor não estão preparados para isso, você precisa que um serviço execute essa tarefa, e por isso eles estão presentes no modelo de domínio do DDD.
Factories:
Em português “Fábricas”, Factories criam objetos, existem cenários quais são impossíveis de definir um objeto sem a criação dele através de uma Factory, sugiro para quem não entende direito o conceito de Factory, a leitura deste exemplo.
Repositório:
Não importa onde esteja alocado seu repositório, em algum momento você vai precisar guardar e recuperar um conjunto de informações como um objeto.
Repositórios não tem regra de negócios, eles fazem a intermediação da sua camada de domínio e sua camada de mapeamento de dados. Pode ser usado NHibernate, Entity Framework entre outros, escolha bem o seu.
Enfim, qualquer abordagem de DDD é muito bem aceito numa metodologia ágil.
Receber os feedbacks dos donos do negócio ao tempo todo é fundamental para uma entrega assertiva. Dentro de uma metodologia ágil programar pequenas entregas é uma boa prática, pois não se inicia no 0% e entrega-se 100% com grandes chances de conter desvios de entendimento.
Sprints, entregas particionadas, diminuem o risco de desvio do entendimento do domínio, assim como do retrabalho.
Lembrando que uma metodologia ágil não faz parte exatamente de uma abordagem de DDD, mas é muito bem vinda.
O DDD é indicado ao meu projeto?
O DDD é indicado para seu projeto caso ele possua um conjunto de regras complexas de negócio, para um sistema simples não é aconselhado o uso de DDD.
Na maioria dos sistemas corporativos são encontradas diversas regras de negócio e cada uma com sua particularidade e complexidade. Iniciar um projeto usando a abordagem de DDD previne que o sistema cresça cada vez mais de uma forma não orientada ao domínio.
TDD – Test-Driven Development (Desenvolvimento Orientado a Testes)
Baseado no DDD e defendido pelo Extreme Programming XP (outra abordagem de programação ágil) é o Desenvolvimento de Software orientado a Testes.
É uma abordagem que oferece muita agilidade dentro do ciclo de desenvolvimento, a ideia é codificar um sistema com 100% de cobertura dos testes.
O processo de desenvolvimento do TDD seria:
Red, Green, Refactor.
- Escrever um teste, sem mesmo ter escrito o código real a ser testado (Figure o que deseja testar).
- Executar os testes e acompanhar a falha (Pode ser um código falso que retorne o erro) (Red)
- Escrevemos a funcionalidade do sistema que iremos testar.
- Testar novamente, agora para passar (Se não passou algo saiu errado, faça novamente o passo 3) (Green)
- Refatore sua funcionalidade e a escreva por completo (o teste também) (Refactor)
- Passe para o próxima estória ou caso de uso e inicie novo teste.
Abaixo um exemplo de caso de teste desenhado:
using System; using NUnit.Framework; namespace TDD.ClienteBanco { [TestFixture] public class ContaTests { [Test] public void TestAporte() { Conta conta = new Conta("Test"); conta.Deposito(500.0); conta.Deposito(70.0); Assert.AreEqual(570.0, conta.Balanco); } } }
Resumindo, é uma prática bem utilizada e entende que o desenvolvimento é feito do teste para o código.
Teste unitário não é tarefa do Tester e sim do desenvolvedor, em muitas empresas um código sem testes unitários nem sobe no repositório. Pense em código, pense em teste de cobertura de código.
Para criação dos testes é bem eficaz a utilização de Mock, Dummy, Fake, Stub, que são considerados dublês de teste, pois se passam por objetos reais sem a necessidade de codificação dos mesmos na etapa da escrita do teste.
Posso utilizar TDD com DDD?
Sim.
Posso utilizar TDD em processos não ágeis?
Sim.
TDD é útil para design de software?
Sim.
Escrever testes após desenvolvimento é TDD?
Não.
BDD – Behavior Driven Development (Desenvolvimento Guiado por Comportamento ou Desenvolvimento Orientado a Comportamento)
Foi originalmente concebido em 2003, por Dan North, como uma resposta ao TDD, tem se expandido muito assim como DDD e TDD.
É uma abordagem que funciona também muito bem com uma metodologia ágil, encorajando desenvolvedores, pessoas de qualidade, não técnicas e de negócios em um projeto de software. Também defende o uso da ubiquitous language como explicado acima facilitando a conversação entre toda equipe envolvida.
Como começa a prática do BDD:
- Envolver as pessoas no processo através de Outside-in Development (Desenvolvimento de Fora pra Dentro)
- Usar exemplos para descrever o comportamento de uma aplicação ou unidades de código
- Automatizar os exemplos para prover um feedback rápido e testes de regressão
- Usar “deve” na hora de descrever o comportamento de software para ajudar esclarecer responsabilidades e permitir que funcionalidades do software sejam questionadas
- Usar dublês de teste (mocks, stubs, fakes, dummies) para auxiliar na colaboração entre módulos e códigos que ainda não foram escritos.
Funcionalidade : [Nome]
Para [ Valor ao Negócio ] Eu, como [ Papel ] Desejo poder realizar [ Funcionalidade ]
Cenário : [ Nome ]
Dado que [ Estado inicial do sistema ] Quando [ Ação a ser realizada no sistema ] Então [ Coisas que o sistema deve fazer após a ação do Quando ]
As palavras Dado que, Quando e Então (Given, When e Then em inglês) são quase sempre usadas para guiar os cenários, não são obrigatórias.
A criação de requisitos para teste podem ser automatizados, existe uma ferramenta chamada SpecFlow, que se adapta ao Visual Studio e suporta o idioma português.
Através do SpecFlow no Visual Studio é necessário adicionar um arquivo do tipo Feature File “.feature” e nele seria escrever uma estória.
Um exemplo bem simples de estória de uma aplicação de vendas poderia ser: “Venda de balas na doceria”.
#language: pt-br
Funcionalidade: Vender doces
Para quando uma doce for vendido
Eu, como vendedor
Desejo decrementar um item no estoque
Cenário: Baixa 1 bala do estoque
Dado que cliente pede 1 bala
E tenho 10 balas em estoque
Quando ele compra realiza a compra
Então eu fico com 9 balas em estoque
Dado esta descrição o SpecFlow irá gerar um arquivo “.feature.cs” que será usado para testes, se rodar os testes após o momento da criação do arquivo com certeza vão falhar, afinal não existe a classe escrita nem a interface desenhada.
É possível fazer testes de interface e end to end sem muito esforço, usando ferramentas como o Watin e também Mock, Dummy, Fake ou Stub como dublês de objetos.
É nesse momento que entra o desenvolvimento da sua aplicação utilizando DDD e/ou TDD (por que não?) e após desenvolvida deve-se complementar o seu arquivo “.feature.cs” com as chamadas da interface para reprodução do requisito desenhado, então você poderá acompanhar o funcionamento do seu negócio com base nesses testes.
Esta é a abordagem do BDD, estimulando os todos envolvidos da equipe, técnicos ou não a escreverem um sistema baseado em comportamentos através de requisitos, estórias, funcionalidades e cenários.
É isso ai pessoal, espero ter abordado o DDD, TDD e BDD de forma clara e que tenha conseguido explicar cada um deles, suas diferenças entre si e como podem ser trabalhados juntos.
Referências:
Estava justamente pesquisando essas definições para mostrar aqui no meu trabalho. Consegui sacar a ideia, muito obrigado!
[ ]’s
Eduardo,
Parabéns pelo artigo, conseguiu explicar de forma simples e clara esses três conceitos que muitos muitas vez trabalham e desconhecem.Irei repassar.
Muito obrigado Armando!
Continue visitando 🙂
Primeiramente, parabéns pelo artigo. Muito Legal.
Estou tentando aplicar BDD no projeto que estou trabalhando, porém estou com uma dúvida:
Em qual camada eu aplico BDD?
O que estou fazendo hoje é BDD na interface com o usuário e TDD nas camadas de Aplicação, Domínio e Infra-estrutura. Estou muito errado?
Olá Alexandre, obrigado por escrever.
Eu costumo pensar em BDD como especificações executáveis.
Você pode usar BDD e TDD juntos na sua camada de Domínio e na interface (principalmente Web) também é comum.
BDD na interface = Outside-In Development (Desenvolvimento de Fora pra Dentro)
O método BDD é guiado pelos benefícios trazidos para o negócio, a melhor maneira de perceber os benefícios de software é através de interfaces gráficas de usuário (“de fora”), pois garantem imediato feedback.
A técnica “outside-in” propõe iniciar pelas interface gráficas e ir “entrando” cada vez mais nas camadas de código e componentes que a interface precisa para atingir plenamente seus objetivos.
Não está errado, só precisaria entender a forma que você está usando o BDD, se não está criando nenhuma limitação desnecessária.
Abraços.
Olá Eduardo! Excelente matéria, estava precisando exatamente disso pra um seminário na faculdade. Agora minha dúvida é: Como poderiam se integrar essas 3 práticas?
Adriano, o uso das três práticas é algo normal, mas para isso é necessário o domínio e entendimento de cada uma para não fazer confusão na hora de usar.
Aconselho estudar cada uma delas separadamente e com o tempo ir integrando o uso, é um processo natural, cada uma possuem características específicas logo o uso das três em conjunto torna-se natural.
Obrigado por postar e precisado de algo deixe sua pergunta.
Abraços.
Olá Eduardo!
Minha pergunta está fora do contexto apresentado, mas seria para elogiar seu blog, ficou bem “clean”, você usou qual ferramenta para desenvolver, foi WordPress?
Olá Reginaldo,
Uso WordPress Self Host (pois assim posso customizar 100% do site).
Qualquer dúvida me escreva em [email protected]
Excelente post! Claro, sucinto e preciso. Parabéns!
Obrigado Fábio!
Abraços.
Excelente post. Vou até utilizar ele como síntese de DDD, TDD e BDD para a minha equipe. Abs.
Obrigado Leandro!
Abraços.
Parabéns Eduardo!
Além de deixar muito claro os conceitos também apresentou ferramentas para ajudar na implementação.
Muito Obrigada,
Ana
Obrigado pelo feedback Ana!
Em breve vou disponibilizar um modelo arquitetonico de projeto com estas 3 abordagens entre outras.
Abraços.
Parabéns pelo post. Muito bom. Obrigada!
Ana Ferraz
Obrigado pelo feedback Ana!
Abs!
Parabéns pelo post.
Obrigado pelo feedback Sousa!
Abs!
Muito esclarecedor, mas possuo uma dúvida com relação a TDD.
Estou iniciando agora na utilização deste conceito que é o TDD e gostaria de saber, quando crio meus testes, eu devo criar um projeto dentro do meu projeto principal apenas para fazer testes?
Se eu crio meus métodos de teste no próprio projeto principal, as tags de teste “[test]” ,”[TestFixture] “, podem ser enviadas no código de produção ?
Sei que são perguntas meio amadoras mas estou começando nesta parte. Agradeço atenção.
E mais uma vez parabéns pelo seu Site. Tenho muitos colegas que acompanham bastante suas postagens.
Jordan,
Sempre crie tudo num projeto de testes separadamente, sempre!
Um projeto de teste para cada projeto, por ex, cada class library (camada) tem seu próprio projeto de testes, isole tudo.
Abs!
Adorei o artigo muito legal, vale a pena mesmo irei começar a implementar
Obrigado pelo feedback Vanessa!
Boa sorte 🙂
Abs!
Muito bom Eduardo como sempre 😀
Você tem exemplos, ou sabe onde eu posso encontrar projetos-exemplo da aplicação de DDD e TDD no github por exemplo? Estou me aprofundando em design patterns para começar a utilizar nos projetos da minha empresa
abraços!
Fala Felipe!
Muito obrigado pelo feedback!
https://www.eduardopires.net.br/2014/10/tutorial-asp-net-mvc-5-ddd-ef-automapper-ioc-dicas-e-truques/
Abs!
Parabéns, muito bem explicado. Ajudou muito!
Boa tarde.
Eduardo, Estou iniciando um pequeno projeto, qual destes modelos seria o ideal?
Boa Eduardo. Material claro e objetivo. Comecei a acompanhar seu site a poucos dias e estou gostando muito. Quando crescer quero ser igual a você (hhaha). Parabéns pelo trabalho!
Eduardo,
Estava estudando seu material que por sinal está muito mbom, e me surgiu a seguinte dúvida, em relação ao domínio, que está em relação ao idioma utilizado para as classes, exemplo a entidade empresa poderia ser chamada de Company.
Neste caso como ficaria a questão do entendimento que é enfatizado em
Ubiquitous Language:
Traduzindo, “Linguagem Onipresente”, é a que está em todo lugar. É a linguagem de quem entende do negócio.
[]´s
Paulo, boa tarde
Acredito que sua resposta está no vídeo abaixo
Vale á pena conferir
Abraço
Muito bom. Muito obrigado pelo post.
Olá Eduardo,
Trabalho com DDD e Fluent NHibernte, no qual gosto muito e acho muito seguro, posso manipular toda a arquitetura e querys.
Meu DDD é em Fluent Nhibernate, tenho aplicações em Win, Web, e Serviços.
Minha duvida é? aplicações onde é toda microsoft.
Vale apena mudar para EF Code First, por mais que esteja imatura?
Muito bom!
Pingback: Os principais conceitos ágeis explicados - Bizstart
Sensacional, amei muito este artigo.
mas gostaria de alguns conselhos teus, eu gostaria de receber mais informações da tua parte no que concerne a webservice no C#, se é uma boa opção desenvolver o projeto complexo com tecnologias .Net (desde o webservice ate a base de dados com o sgbd MS-SQLSERVER) sabendo que terei de lidar com um crescimento escalar veloz e com ate 10.000.000 de informações sendo percistentemente acessadas com e com o mesmo numero de usuarios.
Sensacional esse material, complementou e evidenciou vários pontos, que apesar de serem passíveis de dedução, não estão presentes em outras fontes, obrigado mesmo por compartilhar
Eduardo, muito bom mesmo, obrigado! Agora tenho uma noção melhor do que realmente isso tudo significa.