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.
Para a criação de testes em .Net é bem recomendado o uso de NUnit.
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.
Como o BDD é guiado pelo comportamento do negócio uma maneira de perceber o benefício produzido é pela interface gráfica, produzindo um feedback rápido para saber se os requisitos descritos através dos comportamentos estão funcionais.Escrevendo um requisito de comportamento do sistema:
Em BDD, um desenvolvedor, ou profissional do setor de qualidade ou até mesmo o cliente podem escrever os testes que basicamente são compostos em duas partes, a definição da funcionalidade a ser implementada (User storie) e os cenários de uso que irão validar este requisito.
A funcionalidade é escrita segundo um padrão:
Funcionalidade : [Nome]
Para [ Valor ao Negócio ]
Eu, como [ Papel ]
Desejo poder realizar [ Funcionalidade ]
Dessa forma fica muito claro a todos quais são os objetivos que uma funcionalidade deseja atingir e é de muito fácil entendimento.
Os cenários acompanham a funcionalidade de forma que demonstram comportamentos para atendê-la:
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: