Clean Code

55
CLEAN CODE Robert C. Martin Renato Chencinski - 09/04/2014 [email protected]

description

Resumão do que achei bacana do livro Clean Code, do Uncle Bob.

Transcript of Clean Code

Page 1: Clean Code

CLEAN CODERobert C. Martin

Renato Chencinski - 09/04/2014

[email protected]

Page 2: Clean Code
Page 3: Clean Code

1) O QUE É CÓDIGO LIMPO

- Michael Feathers - Clean code always looks like it was written by someone who cares.

- Ron Jeffries / Kent Beck

1) Run all tests

2) No duplication

3) Express design ideas

4) Minimizes # of entities (classes, methods, ..)

Page 4: Clean Code

1) O QUE É CÓDIGO LIMPO

- Ward Cunningham - Each routine you read is pretty much what you expected

Page 5: Clean Code

1) O QUE É CÓDIGO LIMPO

Paradigma: Razão de tempo lendo código vs escrevendo: > 10:1

- Fazer software fácil de ler é fazer ele fácil de escrever

- Código enxuto, sem textos poluindo que atrasem entendimento

- Poucos comentários

- Classes / funções pequenas

- Níveis de abstração coerentes com contexto

- Código expressivo

Page 6: Clean Code

COMO MEDIR SE CÓDIGO É LIMPO?

Page 7: Clean Code

COMENTÁRIOSComentário desatualizado

/**

* Always returns true.

*/

public boolean isAvailable() {

return false;

}

//private instance variable for storing age

public static int age;

http://stackoverflow.com/questions/184618/what-is-the-best-comment-in-source-code-you-have-ever-encountered?page=1&tab=votes#tab-top

Page 8: Clean Code

COMENTÁRIOSComentário inusitado

// somedev1 - 6/7/02 Adding temporary tracking of Login screen

// somedev2 - 5/22/07 Temporary my ass

Page 9: Clean Code

COMENTÁRIOSComentários úteis

return 1; # returns 1

i++; // increase i by 1

Page 10: Clean Code

FÁCIL LEITURA E ENTENDIMENTOGlobalConfiguration.Configuration.Filters.Add(new HandleAndLogErrorAttribute());

ViewEngines.Engines.RemoveAt(1);

Domains = Empresa.SelectAllURLs(new Context()).ToDictionary(e => e.Dominio, e => new ViewTema() { ViewNome = e.ViewNome, Tema = e.Tema });

ViewEngines.Engines.Add(new CustomViewEngine(Domains));

Page 11: Clean Code

FÁCIL LEITURA E ENTENDIMENTOGlobalConfiguration.Configuration.Filters.Add(new HandleAndLogErrorAttribute());

ViewEngines.Engines.RemoveAt(1);

Domains = ObtemViewsETemasDaEmpresa();

ViewEngines.Engines.Add(new CustomViewEngine(Domains));

Page 12: Clean Code

FÁCIL LEITURA E ENTENDIMENTO

public static KeyValuePair<string, ViewTema> FindDominio(Dictionary<string, ViewTema> dominios, Uri url) {

return dominios.FirstOrDefault(e => e.Key.Split(';').FirstOrDefault(s => String.Equals(s, url.Authority, StringComparison.CurrentCultureIgnoreCase)) != null);

}

Page 13: Clean Code

FÁCIL LEITURA E ENTENDIMENTO

[Código de função gigante]

Page 14: Clean Code

2) NOMES SIGNIFICATIVOS

- Revelam intenção

- int elapsedTimeInDays

- Usar constantes para explicar valores

- cell[0] -> cell[STATUS_VALUE]

- Refactor nos nomes sempre para deixar mais significativo

Page 15: Clean Code

2) NOMES SIGNIFICATIVOS

public List<int[]> getThem() {

List<int[]> list1 = new ArrayList<int[]>();

for (int[] x : theList)

if (x[0] == 4)

list1.add(x);

return list1;

}

Page 16: Clean Code

2) NOMES SIGNIFICATIVOS

public List<Cell> getFlaggedCells() {

List<Cell> flaggedCells = new ArrayList<Cell>();

for (Cell cell : gameBoard)

if (cell.isFlagged())

flaggedCells.add(cell);

return flaggedCells;

}

Page 17: Clean Code

3) FUNÇÕES

PEQUENAS

Page 18: Clean Code

3) FUNÇÕES

PEQUENAS

Page 19: Clean Code

3) FUNÇÕES (PEQUENAS!)

Page 20: Clean Code

3) FUNÇÕES (PEQUENAS!)

Page 21: Clean Code

3) FUNÇÕES (PEQUENAS!)

Page 22: Clean Code

3) FUNÇÕES (PEQUENAS!)

Page 23: Clean Code

3) FUNÇÕES (PEQUENAS!)

- Empírico

- Anos 80 - não maior que altura da tela (24 linhas)

- 20 linhas no máximo do máximo

- Blocos e indentações

- Por ser pequena, if / while / etc terão 1 ou 2 linhas

- Indentação 1 ou 2

Page 24: Clean Code

3) FUNÇÕES (PEQUENAS!)

Funções devem fazer UMA coisa.

Devem fazer isso bem.

Devem fazer apenas isso.

- O que é 1 coisa?

- Apenas 1 nível de abstração abaixo do nome da função.

- Consegue descrever em uma sentença.

Page 25: Clean Code

3) FUNÇÕES (PEQUENAS!)

Page 26: Clean Code

3) FUNÇÕES (PEQUENAS!)

- Níveis de abstração:

- Alto - getHtml

- Médio - String pagePath = PathParser.render(pagePath)

- Baixo - append("\n")

- Misturar níveis confunde, dificulta para o leitor saber se é importante ou se é detalhe

Page 27: Clean Code

3) FUNÇÕES (PEQUENAS!)

- Usar nomes descritivos

- Difícil superestimar valor de bons nomes

- Quanto menor e mais focada função, mais fácil será dar nome

- Melhor nome longo que comentário

- Não ter medo de usar tempo para escolher nome bom

testableHtml -> includeSetupAndTeardownPages

Page 28: Clean Code

3) FUNÇÕES (PEQUENAS!)

- Argumentos

- 0 - ideal

- 1-2 - normal

- 3 - evitar ao máximo

- 4+ - não usar

- Dificultam muito entendimento

- Dificulta testes - casos de teste crescem exponencialmente

- Usar variável membro de classe ao invés de passar arg de fç pra outra

Page 29: Clean Code

3) FUNÇÕES (PEQUENAS!)- Casos principais de acordo com qtde de argumentos

- 1

- Fazer pergunta

- fileExist("myFile")

- Operar sobre argumento e transformar em algo e retornar

- InputStream FileOpen("MyFile")

- Flags

- Muito ruim, indício que função está fazendo mais de uma coisa

- Ex:

- .render(true)

- ininteligível

- mouse over render -> bool isSuite

- menos ruim

- render(isSuite)

- renderForSuite() / renderForSingleTest()

- 2

- Point p(0,0)

- 3

- assertEquals(1.0, ammount, 0.001)

Page 30: Clean Code

3) FUNÇÕES (PEQUENAS!)

- NÃO GERAR EFEITOS COLATERAIS

- Não faça coisas escondidas

- checkPassword(username, pass)

...

session.Initialize()

checkPasswordAndInitializeSession()

Melhor, mas já fica evidente que viola "faça uma coisa"

Page 31: Clean Code

3) FUNÇÕES (PEQUENAS!)

Princípio DRY

DON'T REPEAT YOURSELF

Duplicação pode ser a raiz de todo o mal em software

Page 32: Clean Code

3) FUNÇÕES (PEQUENAS!)

- Como escrever código bom assim?

- É igual escrever livro -> 1o põe idéias no papel, depois refina

- Passos

- Escreve rascunho

- Testes para tudo

- Refatora até ficar bom

NÃO É ESPERADO QUE 1A VEZ SEJA PERFEITO

Page 33: Clean Code

3) FUNÇÕES (PEQUENAS!)

- Mudança incremental, MANTENDO TESTES PASSANDO, um passo de cada vez (baby steps)

Page 34: Clean Code

3) FUNÇÕES (PEQUENAS!)

Arte de programar é a arte de design de idioma

Funções são a linguagem para ajudar a contar história do sistema

Page 35: Clean Code

4) COMENTÁRIOS

- Explique-se por código- Comentários bons

- Informações legais- Explicação de intenção- Aviso de consequências

Page 36: Clean Code

4) COMENTÁRIOS

Page 37: Clean Code

4) COMENTÁRIOS

Page 38: Clean Code

4) COMENTÁRIOS

Page 39: Clean Code

4) COMENTÁRIOS

- Comentários ruins- Comentar só por achar que precisa comentar- Redundantes- Ruído- Código comentado- Excesso de informação

Page 40: Clean Code

4) COMENTÁRIOS

- Comentários ruins- Comentar só por achar que precisa comentar- Redundantes- Ruído- Código comentado- Excesso de informaçãoNão use comentário onde você pode usar uma função ou

variável

Page 41: Clean Code

4) COMENTÁRIOS

Page 42: Clean Code

4) COMENTÁRIOS

Page 43: Clean Code

4) COMENTÁRIOS

- Código comentado- Por que essas 2 linhas estão comentadas? São importantes?- Outros não terão coragem de apagar, por achar que pode ser

importante

Page 44: Clean Code

17) BAD SMELLS

Page 45: Clean Code

17) BAD SMELLS

- Código comentado- Comentário ao invés de código- Comentário obsoleto- Argumentos demais em função- Código em nível errado de abstração

Page 46: Clean Code

17) BAD SMELLS

- Usar variáveis explanatórias

Matcher match = headerPattern.matcher(line);

if(match.find())

{

headers.put(match.group(1), match.group(2));

}

Page 47: Clean Code

17) BAD SMELLS

- Usar variáveis explanatórias

Matcher match = headerPattern.matcher(line);

if(match.find())

{

String key = match.group(1);

String value = match.group(2);

headers.put(key.toLowerCase(), value);

}

Page 48: Clean Code

17) BAD SMELLS

- Constantes no lugar de números mágicos

O que é mais fácil de entender, e de procurar?

assertEquals(7777, Employee.find(“John Doe”).employeeNumber());

assertEquals(

HOURLY_EMPLOYEE_ID,

Employee.find(HOURLY_EMPLOYEE_NAME).employeeNumber());

Page 49: Clean Code

17) BAD SMELLS

- Encapsular condições

if (timer.hasExpired() && !timer.isRecurrent())

if (shouldBeDeleted(timer))

Page 50: Clean Code

17) BAD SMELLS

- Função fazer mais de uma coisa

Page 51: Clean Code

17) BAD SMELLS

- Testes- Insuficientes- Não ter relatório de cobertura de testes

Page 52: Clean Code

OBSERVAÇÕES PESSOAIS

- Refactor para deixar sempre código melhor do que pegou- Para permitir Refactor:

- Testes- Testes- Testes

- Code Review – forma excelente de refactor e aprender

Page 53: Clean Code

OBSERVAÇÕES PESSOAIS

- Testes- F.I.R.S.T. - Fast, Independent, Repeatable, Self-

Validating, Timely

Page 54: Clean Code

OBSERVAÇÕES PESSOAIS

Funções e classes pequenas

Facilita entendimento, cada bloco só ter 1 nível de abstração

“Fazer uma coisa” é mais fácil de ser seguido

Comentários bem menos necessários

Evita indentação excessiva que complica entendimento

Facilita ver começo e fim de bloco (ex: if-else), sem precisar rolar página pra cima e pra baixo

Page 55: Clean Code

Bora escrever código limpo?