5. @dudumendes
O sistema OO com TDD
Seguir o processo do TDD
Construir o sistema através de uma funcionalidade
de cada vez
Quantidade de código crescendo
a única maneira de continuar a entender e
mantê-lo
estruturação das funcionalidades em
objetos, objetos em módulos, módulos em
6. @dudumendes
02 estratégias
SoC (Separation of Concerns, Parnas, 1974)
quando se deseja mudar o comportamento de um
sistema, deve-se puder ir direto ao ponto
Níveis altos de abstração
Evita-se o trato com a complexidade através da
abstração
combinação de componentes ao invés de
variáveis e estruturas de controle
8. @dudumendes
Encapsulamento x
Ocultação
Encapsulamento
O comportamento de um objeto só deve ser alterado através de sua própria
API
Consequência
Ausência de dependências inesperadas entre componentes sem relação
Controle do quanto uma mudança em um objeto irá impactar em outras
partes do sistema
Ocultação de informações
Um objeto esconde como implementa suas funcionalidades através da
abstração de sua API
Ignoram-se os detalhes de baixo nível
9. @dudumendes
Dentro e fora do objeto
Uma decisão de projeto
O que está dentro e fora de cada objeto?
para que o objeto possua uma API coerente
Comunicação entre objetos
mensagens
diretamente com seus vizinhos
Importância
Facilidade de uso de um objeto
Como ele contribui para a qualidade do sistema
10. @dudumendes
Excesso de exposição
Consequências
Vizinhos farão parte do próprio trabalho do objeto
Comportamento distribuído através de muitos
objetos
Forte acomplamento
Alto custo de manutenção
12. @dudumendes
Evitar “e”, “ou” e “mas”
Cada objeto deve possuir uma única e bem definida
funcionalidade
Guia de
quando adicionar funcionalidades a um novo
objeto
criar um novo vizinho para o mesmo
Deve-se poder descrever o que um objeto faz sem
usar conjunções como “e” , “ou”
13. @dudumendes
Tipos de Vizinhos
o que estes objetos dizem um ao outro?
Dependência
Contexto
A funcionalidade de um objeto depende dos
serviços de outros objetos
Consequência
Não é possível criar um objeto sem os demais
14. @dudumendes
Tipos de Vizinhos
o que estes objetos dizem um ao outro?
Notificações
Contexto
Objetos que precisam se manter atualizados das
atividades de seus vizinhos
Não precisa saber necessariamente quem está
“ouvindo”
Consequência
Desacoplamento de vizinhos
15. @dudumendes
Tipos de Vizinhos
o que estes objetos dizem um ao outro?
Ajustes
Contexto
Vizinhos que ajustam o comportamento dos
objetos a partir das necessidades mais amplas do
sistema
Exemplo
Objetos de Layout que ajustam a disponibilização
de elementos
16. @dudumendes
O que mais importa é o
contexto
Não são regras
Nos ajudam a pensar no projeto do código a partir da
perspectiva de suas colaborações
O que é um objeto válido?
Um mesmo objeto pode atuar em mais de um papel
17. @dudumendes
Composições simples
mais que a soma das partes
Utilização de Associações
Objetos compostos devem
fornecer um comportamento mais simples que
a junção de todos os seus componentes
devem ocultar a existência de seus componentes
expor uma abstração simples de seus vizinhos
21. @dudumendes
Independência de contexto
Contexto
Um objeto não deve ser implementado dependendo
de conhecimento sobre o sistema
Se necessário, ele deve receber esta informação
Objetos com contextos independentes
Relações explícitas
Objetos mais simples
Sistema mais fácil de absorver mudanças
23. @dudumendes
Princípios
SOC Saber o que faz
Abstração Não como faz
Encapsulamento Unidades coerentes
Ocultação de Independentes do
informações ambiente
Vizinhança Flexibilidade
Composições simples Adaptação mudanças
24. @dudumendes
TDD / Princípios
Iniciar com um teste
Descreve-se o que um objeto fa antes de considerar o como
Foco
nível de abstração correta
Teste com intenção obscura
mistura de conceitos
não é hora de codificar
Ocultação de informações
decidir o que deve ser visível a partir do objeto
25. @dudumendes
TDD / Princípios
Manter testes legíveis
Limite de escopo
Testes muito grandes
Sujeitos são muitos grandes
quebrar em componentes menores
Objetos compostos
devem possuir separação clara de interesses
passíveis de testes simples
26. @dudumendes
TDD / Princípios
Conhecimento das dependências
Um sujeito em teste precisará de suas dependências
Consequência
Passamos a conhecer as dependências
Melhora-se o entendimento
Apóia a independência de contexto
Dependências implícitas
pode ser trabalhoso de preparar
pode ser necessário “emagrecê-lo”
27. @dudumendes
Interface / Protocolo
Interface
descreve se 02 componentes se encaixam
Protocolo
descreve se eles trabalham juntos
O TDD torna visível o protocolo de comunicação entre
os objetos
28. @dudumendes
Adicionando funcionalidades
Surgimento de códigos de novas áreas
Ao iniciar novas áreas de código
deve-se esquecer temporariamente julgamentos sobre projeto
apenas escrever código sem se importar com estrutura
Consequência
Ganha-se confiança e experiência
Entende-se as intenções do código
Entretanto código pode se tornar muito grande
29. @dudumendes
Teste informam
Fragmentar um objeto
se ele se tornou muito grande para se testar
facilmente
se falhas de teste se tornaram difíceis de se
interpretar
se o domínio está disperso
32. @dudumendes
Contexto
Para aplicações que dependem de ambientes de
execução, escrever testes pode ser um desafio
Testes precisam ser estáveis e quando executados
repetidamente eles devem gerar os mesmos
resultados
É necessário um modo de controlar o ambiente em
que os testes são executados
33. @dudumendes
Soluções
Configurar o ambiente real
pode ser prático e trazer benefícios reais
nem sempre é viável
Simular o que está faltando
substituindo por um por algo falsificado que se
comporte do mesmo jeito
38. @dudumendes
Testes Dublês
Dummy Objects
são repassados como parâmetros
mas nunca utilizados
it “deve possuir um nome” do
e = Endereco.new
c = Cliente.new(“Cliente 1”, e)
expect(c.nome).to eql(“Cliente 1”)
end
39. @dudumendes
Testes Dublês
Fake Objects
Objeto que possuem implementações
funcionais, mas normalmente utilizam algum atalho
que os torna inadequados para produção
Ex: Bancos de dados em memória
40. @dudumendes
Testes Dublês
Stubs
Objetos que providenciam respostas pré-
configuradas para as chamadas feitas durante os
testes
Normalmente, não respondem nada além do que
esteja previamente programado para o teste
As respostas são estáticas
42. @dudumendes
describe Statement do
it “usa o nome do cliente” do
cliente = double(‘cliente’)
cliente.stub(:nome).and_return(“Joao”)
statement = Statement.new(cliente)
statement.generate.should == “Sentenca do Joao”
end
43. @dudumendes
Testes Dublês
Spy
Comportamento semelhante ao Mock, mas as
verificações de comportamento são realizadas após
o método testado ser chamado
É capaz de verificar se um determinado método foi
chamado pois pode gravar informações
45. @dudumendes
Testes Dublês
Mocks
Expectativas dos objetos são
pré-programadas antes de se executar um método a
ser testado
Objetos fornecem o comportamento correto das
chamadas que esperam receber