tdd projeto e estrategias
DESCRIPTION
Considerações sobre um bom projeto orientado a objeto e como o TDD apoia a alcançar um bom projetoTRANSCRIPT
DesenvolvimentoBaseado em TestesProjeto e EstratégiasEduardo [email protected]
@dudumendes
Introdução
@dudumendes
Introdução
O que se quer de um bom projeto
Princípios para alcançar
Situações que esclareçam
@dudumendes
Manutenibilidade
@dudumendes
O sistema OO com TDDSeguir 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
@dudumendes
02 estratégiasSoC (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
@dudumendes
Combinação de componentes
Como dividir o código em componentes?
Quais os limites das interfaces de comunicação?
@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
@dudumendes
Dentro e fora do objetoUma 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
@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
@dudumendes
Excesso de exposição
master.getModelisable().getDockable()
.getCustomizer().getSaveItem.
setEnabled(TRUE)
@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”
@dudumendes
Tipos de Vizinhoso 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
@dudumendes
Tipos de Vizinhoso 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
@dudumendes
Tipos de Vizinhoso 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
@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
@dudumendes
Composições simplesmais 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
@dudumendes
moneyEditor.getAmountField().setText(String.valueOf(money.amount)moneyEditor.getCurrencyField().setText(money.currencyCode)
@dudumendes
moneyEditor.setAmountField(money.amount)moneyEditor.setCurrencyField(money.currencyCode)
@dudumendes
moneyEditor.setValue(money);
@dudumendes
Independência de contextoContexto
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
@dudumendes
TDD x Princípios
@dudumendes
PrincípiosSOC
Abstração
Encapsulamento
Ocultação de informações
Vizinhança
Composições simples
Saber o que faz
Não como faz
Unidades coerentes
Independentes do ambiente
Flexibilidade
Adaptação mudanças
@dudumendes
TDD / PrincípiosIniciar 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
@dudumendes
TDD / PrincípiosManter 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
@dudumendes
TDD / PrincípiosConhecimento 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”
@dudumendes
Interface / ProtocoloInterface
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
@dudumendes
Adicionando funcionalidadesSurgimento 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
@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
@dudumendes
Testes e dependências
@dudumendes
Contexto
Componente!
Dependencia!
Associação!Composição!
@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
@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
@dudumendes
Estratégia
Componente!
@dudumendes
Estratégia
Componente!
Mock!
Mock!Mock!
Falso
FalsoFalso
@dudumendes
Dublês de TestesTest DoublesMESZAROS
@dudumendes
Double
Dummy Fake Mock Stub Spy
@dudumendes
Testes DublêsDummy Objects
são repassados como parâmetros
mas nunca utilizados
it “deve possuir um nome” doe = Endereco.newc = Cliente.new(“Cliente 1”, e)
expect(c.nome).to eql(“Cliente 1”)end
@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
@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
@dudumendes
Stub
Fonte: MEZAROS, 2007
@dudumendes
describe Statement doit “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
@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
@dudumendes
Spy
Fonte: MEZAROS, 2007
@dudumendes
Testes Dublês
Mocks
Expectativas dos objetos sãopré-programadas antes de se executar um método a ser testado
Objetos fornecem o comportamento correto das chamadas que esperam receber
@dudumendes
Mock
Fonte: MEZAROS, 2007
@dudumendes
Bibliografia
FOWLER, Martin. “Mocks aren’t Stubs”.
FREEMAN, Steve; PRYCE, Nat. Growing Object-Oriented Software, Guiaded by Tests. Addison-Wesley.
MESZAROS, Gerard. xUnit Test Patterns: RefactoringTest Code. Addison-Wesley: 2007
MESZAROS, Gerard. xUnitTest Patterns.com. http://xunitpatterns.com/