tdd projeto e estrategias

Post on 06-Jul-2015

238 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Considerações sobre um bom projeto orientado a objeto e como o TDD apoia a alcançar um bom projeto

TRANSCRIPT

DesenvolvimentoBaseado em TestesProjeto e EstratégiasEduardo Mendesedumendes@gmail.com

@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/

top related