Vamos falar de Clean Code, Refatoração e TDD

Post on 11-Jun-2015

678 views 4 download

description

Slides da palestra ministrada no 4º E-TIC do Instituto Federal de Camboriu. Escrever código com baixa qualidade, de forma ilegível e confusa pode até funcionar!Tais atitudes,conscientes ou não, resultam na contração de uma dívida que cobra juros altos,perda de produtividade. Serão abordados tópicos relacionados principalmente a responsabilidade e profissionalismo no desenvolvimento de software. Pontos importantes como motivação, qualidade de código, métricas, técnicas de refactoring, desenvolvimento orientado a testes e boas práticas para manter o código limpo e evitar muitas dores de cabeça no futuro!

Transcript of Vamos falar de Clean Code, Refatoração e TDD

Vamos falar de Clean Vamos falar de Clean Code, Refatoração e Code, Refatoração e TDD mais uma vezTDD mais uma vez

Domingos TeruelZend Certified Engineer

Domingos TeruelZend Certified Engineer PHP 5.3

Tecnólogo em Processamento de dados e Gestão da Tecnologia da Informação,

especialista em interfaces de sistemas, atuando no desenvolvimento e

implementação de sistemas web com software livre e Governo Eletrônico.

Sobre o que vamos falar?Sobre o que vamos falar?

Profissionalismo e felicidadeProfissionalismo e felicidade

Insatisfação com o fracassoInsatisfação com o fracasso

Existe diferença?Existe diferença?

Insatisfação no trabalhoInsatisfação no trabalho

Você se sente profissional?Você se sente profissional?

Você se sente profissional?Você se sente profissional?

Você se sente profissional?Você se sente profissional?

Poderia ser mais produtivo?Poderia ser mais produtivo?

Sensação de impotênciaSensação de impotência

Se sente um peão de obra, trabalho braçal Se sente um peão de obra, trabalho braçal e desgastante!e desgastante!

Se sente um peão de obra, trabalho braçal Se sente um peão de obra, trabalho braçal e desgastante!e desgastante!

Qual a diferença entre cansaço e Qual a diferença entre cansaço e stress?stress?

Já teve aquele sentimento de largar

tudo?

O que mais motiva um O que mais motiva um desenvolvedor?desenvolvedor?

“Quem trabalha apenas pelo salário, ganhe o que for, será

sempre mal pago.”

(Autor desconhecido)

“Qual é a sua obraobra? Quando você se for, o

vai restar?”

(Mario Cortella)

Afinal, quanto custa a Afinal, quanto custa a bagunçabagunça para a empresa? para a empresa?

Afinal, quanto custa a Afinal, quanto custa a bagunçabagunça para a empresa? para a empresa?

Alta rotatividadeAlta rotatividade

Demora no lançamento de novas Demora no lançamento de novas funcionalidadesfuncionalidades

Demora no lançamento de novas Demora no lançamento de novas funcionalidadesfuncionalidades

Dificuldade na hora de realizar Dificuldade na hora de realizar qualquerqualquer modificação...

Alta incidência de bugs?Alta incidência de bugs?

Quanto custa a falta deconfiança do seu cliente?

Quanto tempo você perde tentando entender o código para corrigir um

bug?

Quanto tempo você perde tentando entender o código para corrigir um

bug?

Conclusão: Passamos a maior parte do tempo lendo o código!

Conclusão: Passamos a maior parte do tempo lendo o código!

Evolução da Produtividade

Clean code, o que é?Clean code, o que é?

Você teria medo de tomar o remédio?

Você teria medo de tomar o remédio?

Código feito com cuidado

Que revela intenção

simplessimples

Fácil de entenderFácil de entender

“Qualquer tolo consegue escrever código que um computador entenda.

Bons programadores escrevem Bons programadores escrevem código que humanos possam código que humanos possam

entender.entender.”

(Martin Fowler)

Funcionar é o mínimomínimo que se

espera.

Qualidade Qualidade Externa x InternaExterna x Interna

Qualidade externaexterna é aquela que você percebe logo de cara. Se ausabilidade da interface for ruim, aperformance for sofrível e defeitos acontecem com frequência, a pessoa logo percebe e sequer compra o software.

Qualidade internainterna é aquela que você só percebe com o tempo. Infelizmente o comercial não vende esse tipo de qualidade. Noentanto, é é ela que atrasa o negócio e mata a ela que atrasa o negócio e mata a empresa aos poucos, sufoca e empresa aos poucos, sufoca e aumenta os custosaumenta os custos. É ela que gera boa parte da rotatividade.

Como medir a qualidade do código?

• Linhas de código?

• Número de métodos?

• Número de classes?

• Linhas de código por método?

• Complexidade ciclomática?

• Número de estruturas de decisão?

?

WTF

WTF

WTF

WTF

WTF

WTF

dificuldade de entenderdificuldade de entender

nivel máximo de sujeiranivel máximo de sujeira

Debate: Até que ponto vale apena continuar mantendo um projeto

vivo?

Debate: Até que ponto vale apena continuar mantendo um projeto

vivo?

Falar é fácilFalar é fácil

O desafio é criar código de qualidade!

O desafio é criar código de qualidade!

No entanto, falar é o primeiro passo rumo a melhoria!

No entanto, falar é o primeiro passo rumo a melhoria!

Quatro estágios necessários para

adquirir novos novos hábitoshábitos

Estágio 1

“Inconsciente e sem “Inconsciente e sem habilidade”habilidade”

Ignoramos o comportamento e o

hábito

Estágio 2

“Consciente e sem “Consciente e sem habilidade”habilidade”

Conhecemos o comportamento mas

ainda não temos o hábito de aplicá-lo”

Estágio 3

“Consciente e “Consciente e habilidoso”habilidoso”

Nos sentimos confortáveis com pela prática que vamos

adquirindo com o tempo

Estágio 4

“Inconsciente e “Inconsciente e habilidoso”habilidoso”

O hábito se torna uma coisa natural

Escrever código limpo requer muita Escrever código limpo requer muita prática e habilidade!prática e habilidade!

Escrever código limpo requer muita Escrever código limpo requer muita prática e habilidade!prática e habilidade!

Començando a treinarComençando a treinar

Nomes estranhosNomes estranhos

Limitação históricaLimitação histórica

1. READ INPUT TAPE A1, B1, C1;2. 501 FORMAT A1;3. IF (A1) 777, 777, 7774. IF (B1) 888, 888, 8885. IF (C1) 999, 999, 9996. STOP 17. 799 S = FLOATF(A1 + B1 + C1) / 2.08. WRITE TO TAPE S9. END PROCESS

As linguagens não ajudavam muito

As linguagens não ajudavam muito

Os ambientes não ajudavam

Os ambientes não ajudavam

Nem os computadoresNem os computadores

Deixaram essa herança maldita!

Deixaram essa herança maldita!

Aprendendo com os mestres

Aprendendo com os mestres

1. // Descrição da maquina2. $m_desc;3. // Resultado parcial da soma4. $s1;5. // Cor dos olhos6. $cOlhos;7. // Valor do índice temporário8. $aux;

revela a intençãorevela a intenção

1. // Descrição da maquina2. $m_desc;3. // Resultado parcial da soma4. $s1;5. // Cor dos olhos6. $cOlhos;7. // Valor do índice temporário8. $aux;

1. // Descrição da maquina2. $descricaoDaMaquina;3. // Resultado parcial da soma4. $resultadoParcialSoma;5. // Cor dos olhos6. $corDosOlhos;7. // Valor do índice temporário8. $valorDoIndiceTemporario;

1.2. $descricaoDaMaquina;3.4. $resultadoParcialSoma;5.6. $corDosOlhos;7.8. $valorDoIndiceTemporario;

1.$descricaoDaMaquina;2.$resultadoParcialSoma;3.$corDosOlhos;4.$valorDoIndiceTemporario;

Não seja genéricoNão seja genérico

1. // Processa folha de pagamento2. processa()processa();3. // Calcula o imposto de renda ret.4. calcula();5. // Renderiza o relatório de alunos6. renderiza();7. // Totaliza as estatísticas da ligação8. totaliza()totaliza();

1. // Processa folha de pagamento2. processaFolhaPagamento()processaFolhaPagamento();3. // Calcula o imposto de renda ret.4. calculaImpostoRetido()calculaImpostoRetido();5. // Renderiza o relatório de alunos6. renderizaRelatorioAlunos()renderizaRelatorioAlunos();7. // Totaliza as estatísticas da ligação8. totalizaEstatisticasLigacao()totalizaEstatisticasLigacao();

1. 2. processaFolhaPagamento()processaFolhaPagamento();3. 4. calculaImpostoRetido()calculaImpostoRetido();5. 6. renderizaRelatorioAlunos()renderizaRelatorioAlunos();7. 8. totalizaEstatisticasLigacao()totalizaEstatisticasLigacao();

1. processaFolhaPagamento()processaFolhaPagamento();2. calculaImpostoRetido()calculaImpostoRetido();3. renderizaRelatorioAlunos()renderizaRelatorioAlunos();4. totalizaEstatisticasLigacao()totalizaEstatisticasLigacao();

Simplifique estruturas de decisão

Simplifique estruturas de decisão

<?phpclass Taximetro { public function calculaValorDaCorrida($hora) { if ($hora > 22:00 || $hora < 06:00) { return $this->distancia * 3.90; } else { return $this->distancia * 2.10; } }}

<?phpclass Taximetro { public function calculaValorDaCorrida($hora) { if () { return $this->distancia * 3.90; } else { return $this->distancia * 2.10; } }}

<?phpclass Taximetro { public function calculaValorDaCorrida($hora) { if ($this->ehBandeiraDois($hora)) { return $this->distancia * 3.90; } else { return $this->distancia * 2.10; } }}

<?phpclass Taximetro { public function calculaValorDaCorrida($hora) { if ($this->ehBandeiraDois($hora)) { return $this->distancia * 3.90; } else { return $this->distancia * 2.10; } } public function ehBandeiraDois($hora) { return $hora > 22:00 || $hora < 06:00; }}

Números mágicosNúmeros mágicos

<?php<?phpclassclass TaximetroTaximetro {{ publicpublic functionfunction calculaValorDaCorridacalculaValorDaCorrida(($hora$hora)) {{ ifif ( ($this->ehBandeiraDois($hora)$this->ehBandeiraDois($hora)) {) { returnreturn $this->distancia ** 3.903.90;; } } elseelse {{ returnreturn $this->distancia ** 2.102.10;; } } } } publicpublic functionfunction ehBandeiraDoisehBandeiraDois(($hora$hora)) {{ returnreturn $hora$hora >> 2222::0000 |||| $hora$hora << 0606::0000;; } }}}

<?php<?phpclassclass TaximetroTaximetro {{ publicpublic functionfunction calculaValorDaCorridacalculaValorDaCorrida(($hora$hora)) {{ ifif ( ($this->ehBandeiraDois($hora)$this->ehBandeiraDois($hora)) {) { returnreturn $$this->distancia **;; } } elseelse {{ returnreturn $$this->distancia **;; } } } } publicpublic functionfunction ehBandeiraDoisehBandeiraDois(($hora$hora)) {{ returnreturn $hora$hora >> 2222::0000 |||| $hora$hora << 0606::0000;; } }}}

<?php<?phpclassclass TaximetroTaximetro {{ publicpublic functionfunction calculaValorDaCorridacalculaValorDaCorrida(($hora$hora)) {{ ifif ( ($this->ehBandeiraDois($hora)$this->ehBandeiraDois($hora)) {) { returnreturn $$this->distancia ** PRECO_B2PRECO_B2;; } } elseelse {{ returnreturn $$this->distancia ** PRECO_B1PRECO_B1;; } } } } publicpublic functionfunction ehBandeiraDoisehBandeiraDois(($hora$hora)) {{ returnreturn $hora$hora >> 2222::0000 |||| $hora$hora << 0606::0000;; } }}}

<?php<?phpclassclass TaximetroTaximetro {{ publicpublic functionfunction calculaValorDaCorridacalculaValorDaCorrida(($hora$hora)) {{ ifif ( ($this->ehBandeiraDois($hora)$this->ehBandeiraDois($hora)) {) { returnreturn $$this->distancia ** PRECO_BANDEIRA2PRECO_BANDEIRA2;; } } elseelse {{ returnreturn $$this->distancia ** PRECO_BANDEIRA1PRECO_BANDEIRA1;; } } } } publicpublic functionfunction ehBandeiraDoisehBandeiraDois(($hora$hora)) {{ returnreturn $hora$hora >> 2222::0000 |||| $hora$hora << 0606::0000;; } }}}

Saindo do labirintoSaindo do labirinto

<?php...function calculaValorDaCorrida($hora) { if ($hora > 22:00 || $hora < 06:00) { return $this->distancia * 3.90; } else { if ($this->diaDaSemana == 'Domingo') { return $this->distancia * 2.9; }else { return $this->distancia * 2.10; } }}...

distância da margemdistância da margem

<?php...function calculaValorDaCorrida($hora) { if ($hora > 22:00 || $hora < 06:00) { return $this->distancia * 3.90; } else { if ($this->diaDaSemana == 'Domingo') { return $this->distancia * 2.9; }else { return $this->distancia * 2.10; } }}...

<?php...function calculaValorDaCorrida($hora) { if () { return $this->distancia * 3.90; } else { if () { return $this->distancia * 2.9; }else { return $this->distancia * 2.10; } }}...

<?php...function calculaValorDaCorrida() { if ($this->ehBandeiraDois()) { return $this->distancia * 3.90; } else { if ($this->ehHorarioDeDomingo()) { return $this->distancia * 2.9; }else { return $this->distancia * 2.10; } }}...

<?php..function calculaValorDaCorrida() { if ($this->ehBandeiraDois()) { return $this->distancia * 3.90; } if ($this->ehHorarioDeDomingo()) { return $this->distancia * 2.9; }else { return $this->distancia * 2.10; }}...

<?php...function calculaValorDaCorrida() { if ($this->ehBandeiraDois()) { return $this->distancia * 3.90; } if ($this->ehHorarioDeDomingo()) { return $this->distancia * 2.9; }else { return $this->distancia * 2.10; }}...

<?php...function calculaValorDaCorrida() { if ($this->ehBandeiraDois()) { return $this->distancia * 3.90; } if ($this->ehHorarioDeDomingo()) { return $this->distancia * 2.9; } return $this->distancia * 2.10;

}...

<?php...function calculaValorDaCorrida() { if ($this->ehBandeiraDois()) { return $this->distancia * PRECO_BANDEIRA2; } if ($this->ehHorarioDeDomingo()) { return $this->distancia * PRECO_DE_DOMINGO; } return $this->distancia * PRECO_BANDEIRA1;} ...

medo de estragar algo?medo de estragar algo?

economize, teste mais cedo!

economize, teste mais cedo!

Mas o que é refatorar?Mas o que é refatorar?

“Alteração feita na estrutura interna do software para torná-

lo mais fácil de ser entendido e menos custoso

de ser modificado sem alterar seu comportamento

observável.”

(Martin Fowler)

“Refactoring é a arte de evoluir o design do código existente.”

(William C. Wake)

“Refatorar é uma forma de manter seu software

sustentável e competitivo com o passar do tempo.”

Refatorar é uma forma de investimento

Refatorar é uma forma de investimento

Tempo investido refatorando é proporcional ao tempo

economizado com o entendimento do código multiplicado pelo número

de pessoas na equipe.

(Rodrigo Branas - Developer)

A fórmula matemática do refactoring:

Tr = Te * tamanho da equipe

1 hora investida refatorando é proporcional a

8 horas economizadas com o entendimento em uma equipe de 8

pessoas.

Isso sem falar em flexibilidade, redução na quantidade de

defeitos e reuso.

infelizmente, o inverso também é verdadeiro

infelizmente, o inverso também é verdadeiro

Como vendervender atividades de refatoração para o seu gerente?

Como vendervender atividades de refatoração para o seu gerente?

Diálogo entre o Desenvolvedor e o Gerente

Desenvolvedor: João, preciso fazer um refactoring no código!Gerente: Refactoring?! O que é isso, você vai melhorar a performance?Desenvolvedor: Não, não...Gerente: Vai deixar a interface mais bonita e mais fácil de ser utilizada?Desenvolvedor: Não...Gerente: Então? O que é isso?Desenvolvedor: “Vou fazer uma alteração na estrutura interna do software,para torná-lo mais fácil de ser entendido e menos custoso de sermodificado, sem alterar seu comportamento observável.” (Martin Fowler)Gerente: Não.

Refatore com um propósito, evite refatorar apenas por

refatorar

Refatore com um propósito, evite refatorar apenas por

refatorar

Atente-se as oportunidadesoportunidades!

Atente-se as oportunidadesoportunidades!

Aproveite a correçãocorreção de um defeito para refatorar!

Aproveite a correçãocorreção de um defeito para refatorar!

Vai adicionaradicionar algo novo, aproveite para refatorar!

Vai adicionaradicionar algo novo, aproveite para refatorar!

Refatore quando precisar entenderentender uma parte do código

Refatore quando precisar entenderentender uma parte do código

Os 7 principais inimigos da Os 7 principais inimigos da refatoraçãorefatoração

Os 7 principais inimigos da Os 7 principais inimigos da refatoraçãorefatoração

DesconhecimentoDesconhecimentoDesconhecimentoDesconhecimento

Não se dar conta do problema é uma das principais causas. É É

comum ver desenvolvedores comum ver desenvolvedores experientes que não dão experientes que não dão

atenção a qualidade do código.atenção a qualidade do código.

ImediatismoImediatismoImediatismoImediatismo

Pensar apenas em resolver o resolver o problemaproblema, sem considerar que a natureza do desenvolvimento

de software é a mudança.

Janelas quebradasJanelas quebradasJanelas quebradasJanelas quebradas

Temos dificuldade em lidar com janelas quebradas. Seja numa

dieta, relacionamento ou desenvolvimento de software, o

desânimo das janelas desânimo das janelas quebradas leva ao fracassoquebradas leva ao fracasso.

Nível técnico baixoNível técnico baixoNível técnico baixoNível técnico baixo

É fácil culpar o estagiário. É preciso ter pessoas com nível

técnico alto e senso crítico apurado para zelar pelas zelar pelas boaspráticas e manter a boaspráticas e manter a

ordem do códigoordem do código.

Falta de trabalho em Falta de trabalho em equipeequipe

Falta de trabalho em Falta de trabalho em equipeequipe

O código pertence a equipe, não ao seu autor.

Todos devem se Todos devem se responsabilizar e zelar responsabilizar e zelar

pelo bem comumpelo bem comum.

GerenciamentoGerenciamentoGerenciamentoGerenciamento

Pressão comercialPressão comercialPressão comercialPressão comercial

Quando não Quando não refatorar?refatorar?

Quando não Quando não refatorar?refatorar?

• Quando o código simplesmente não funciona, é instáveé instável

• Se funciona, ninguém sabe ao ninguém sabe ao certo comocerto como......

• Próximo ao final do prazo de prazo de entregaentrega

A maioria das empresas precisa contrair algumas dívidascontrair algumas dívidas para

funcionar efetivamente

A maioria das empresas precisa contrair algumas dívidascontrair algumas dívidas para

funcionar efetivamente

Mas cuidado com o aumento do débito débito técnicotécnico, os juros são altos

Mas cuidado com o aumento do débito débito técnicotécnico, os juros são altos

Testes unitáriosTestes unitários

As 3 leis do TDDAs 3 leis do TDD

• Você não pode escrever o código Você não pode escrever o código até que tenha criado um teste até que tenha criado um teste falhandofalhando;

• Você não pode escrever mais Você não pode escrever mais testes do que seja suficiente para testes do que seja suficiente para falharfalhar;

• Você não pode escrever mais Você não pode escrever mais código do que o suficiente para código do que o suficiente para passar o teste que esta falhandopassar o teste que esta falhando;

1 Conceito por teste1 Conceito por teste

• Separe do teste que esteja testando com mais de um mais de um conceitoconceito em outros testes

• FaciliteFacilite o entendimento de cada teste

Os testes devem ser rápidosrápidos para executar,

pois quando são lentos a frequência de execução

diminui.

Testes não podem depender uns dos depender uns dos

outros,outros, pois se um falha os outros também

falharam

Ao executa-los mais de uma vez, devem sempre

retornar o mesmoretornar o mesmo resultado

Os testes devem ser devem ser escritos antes do escritos antes do

códigocódigo. Após o código será mais

difícil fazer o teste

O código do teste é tão código do teste é tão importante quanto o importante quanto o código da produção.código da produção.O teste precisa sofrer

alterações da mesma forma que o código

Quanto mais sujo o teste mais difícil mais difícil dar

manutenção, e menor a menor a flexibilidadeflexibilidade para alterá-

lo.

“Se você deixar seus testes apodrecerem, seu código também

apodrecerá”

Fique atento aos maus cheiros!

Fique atento aos maus cheiros!

• Comentários pobres, obsoletos e redundantes

• Código comentado

• Testes que requerem mais de um passo

• Muitos parâmetros ou parâmetros booleanos

• Métodos mortos ou que fazem muita coisa

• Responsabilidades fora do contexto

• Nomes pequenos e inexpressivos

• Duplicação

• Inconsistência

• Intenção obscura

• Variáveis e funções inexpressivas

• Despadronização

• Números mágicos

• Desencapsulamento

• Efeitos colaterais

• Testes insuficientes

ConclusãoConclusão

• Tudo o que falamos até aqui não é para ser uma lista de regras

• Você não se torna um bom programador aprendendo uma lista de regras.

• As técnicas e práticas têm que começar a fazer parte do nosso dia a dia.

• Devemos nos preocupar com a qualidade do código e não somente fazê-lo funcionar.

Você é responsável pelo código que escreve e só você!

Você é responsável pelo código que escreve e só você!

ReferênciaReferência

• Clean Code - Robert Martin

• Refactoring - Martin Fowler

• Patters of Enterprise Application Architecture - Martin Fowler

• Test-Driven Development by Example - Kent Beck

• Effective Java - Joshua Block

• Design Patterns - Eric Gamma, Richard Helm, Ralph Johnson e John Vlissides

• Design Patterns - Head First - Eric Freeman e Elisabeth Freeman

• Refactoring to Patterns - Joshua Kerievisky

• Domain-Driven Design - Eric Evans

• Working Effectively with Legacy Code - Michael Feathers

• Baseado no curso de Clean Code por Rodrigo Branas (www.agilecode.com.br)

ReferênciaReferência

Perguntas?Perguntas?

Participe!

dteruel@opensuse.org http://about.me/mingomax