object calisthenics: relaxe e escreva códigos simples

55
Object Calisthenics: relaxe e escreva códigos simples Goiânia, 23 de Março de 2013 Otávio Calaça Xavier [email protected]

Upload: otavio-calaca-xavier

Post on 25-May-2015

444 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Object Calisthenics: relaxe e escreva códigos simples

Object Calisthenics:relaxe e escreva

códigos simples

Goiânia, 23 de Março de 2013

Otávio Calaça Xavier

[email protected]

Page 2: Object Calisthenics: relaxe e escreva códigos simples

Criado em dezembro de 2007; Lista de Discussão:

− Mais de 650 membros.

Projetos:− Encontros mensais;− Softwares Livres em PHP;− Networking.

Eventos:• FLISOL, FGSL, Latinoware, Conisli, CONSOFT, PHP

Conference Brasil, FISL, Join Community …

Precisamos de Colaboradores!!!

Grupo de Desenvolvedores PHP de Goiás

www.gophp.org.br

Page 3: Object Calisthenics: relaxe e escreva códigos simples

3

Object Calisthenics: relaxe e escreva códigos simples

Roteiro

• Motivação;

• Orientações;

• Aplicação.

Page 4: Object Calisthenics: relaxe e escreva códigos simples

4

Object Calisthenics: relaxe e escreva códigos simples

Por que meu código é ruim?

• Ele é legível?• Ele é testável?• Ele é de fácil manutenção?• Ele é reusável?

Page 5: Object Calisthenics: relaxe e escreva códigos simples

5

Object Calisthenics: relaxe e escreva códigos simples

Object Calisthenics

• Calistenia = exercício de relaxamento; ginástica rítimica;

• Uma variedade de exercícios simples e rítimicos para alcançar melhor qualidade de código e OO.

Page 6: Object Calisthenics: relaxe e escreva códigos simples

6

Object Calisthenics: relaxe e escreva códigos simples

Object Calisthenics

• Jeff Bay em The ThoughtWorks Anthology definiu o termo Object Calisthenics para a computação, como o conjunto de exercícios para a programação Orientada a Objetos.

Page 7: Object Calisthenics: relaxe e escreva códigos simples

7

Object Calisthenics: relaxe e escreva códigos simples

Object Calisthenics

• Orientações:– Nove (9) orientações simples e que

podem ser utilizadas em qualquer linguagem orientada a objetos.

Page 8: Object Calisthenics: relaxe e escreva códigos simples

8

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO I

somente um nível de identação/recuo por método.

Page 9: Object Calisthenics: relaxe e escreva códigos simples

9

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO I somente um nível de identação/recuo por método

public function validarProdutos($produtos) { $camposRequeridos = array( 'nome', 'preco', 'descricao', 'tipo' ); $valido = true; foreach($produtos as $produto) { $campos = array_keys($produto); foreach ($camposRequeridos as $campoRequerido) { if(!in_array($campoRequerido, $campos)) { $valido = false; } } } return $valido; }

Page 10: Object Calisthenics: relaxe e escreva códigos simples

10

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO I somente um nível de identação/recuo por método

public function validarProdutos($produtos) { $camposRequeridos = array( 'nome', 'preco', 'descricao', 'tipo' ); $valido = true; foreach($produtos as $produto) { $campos = array_keys($produto); foreach ($camposRequeridos as $campoRequerido) { if(!in_array($campoRequerido, $campos)) { $valido = false; } } } return $valido; }

Page 11: Object Calisthenics: relaxe e escreva códigos simples

11

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO I somente um nível de identação/recuo por método

public function validarProdutos($produtos) { $camposRequeridos = array( 'nome', 'preco', 'descricao', 'tipo' ); $valido = true; foreach($produtos as $produto) { $campos = array_keys($produto); foreach ($camposRequeridos as $campoRequerido) { if(!in_array($campoRequerido, $campos)) { $valido = false; } } } return $valido; }

0

12

3

Page 12: Object Calisthenics: relaxe e escreva códigos simples

12

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO I somente um nível de identação/recuo por método

public function validarProdutos($produtos) { $camposRequeridos = array( 'nome', 'preco', 'descricao', 'tipo' ); $valido = true; foreach($produtos as $produto) { $validacao = $this->validarProdutoIndividual($produto, $camposRequeridos); if( ! $validacao) { $valido = false; } } return $valido; } public function validarProdutoIndividual($produto, $camposRequeridos) { $valido = true; $campos = array_keys($produto); foreach ($camposRequeridos as $campoRequerido) { if( ! in_array($campoRequerido, $campos)) { $valido = false; } } }

Page 13: Object Calisthenics: relaxe e escreva códigos simples

13

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO I somente um nível de identação/recuo por método

public function validarProdutos($produtos) { $camposRequeridos = array( 'nome', 'preco', 'descricao', 'tipo' ); $valido = true; foreach($produtos as $produto) { $validacao = $this->validarProdutoIndividual($produto, $camposRequeridos); if( ! $validacao) { $valido = false; } } return $valido; } public function validarProdutoIndividual($produto, $camposRequeridos) { $valido = true; $campos = array_keys($produto); foreach ($camposRequeridos as $campoRequerido) { if( ! in_array($campoRequerido, $campos)) { $valido = false; } } }

Page 14: Object Calisthenics: relaxe e escreva códigos simples

14

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO I somente um nível de identação/recuo por método

public function validarProdutos($produtos) { $camposRequeridos = array( 'nome', 'preco', 'descricao', 'tipo' ); $valido = true; foreach($produtos as $produto) { $validacao = $this->validarProdutoIndividual($produto, $camposRequeridos); if( ! $validacao) { $valido = false; } } return $valido; } public function validarProdutoIndividual($produto, $camposRequeridos) { $valido = true; $campos = array_keys($produto); foreach ($camposRequeridos as $campoRequerido) { if( ! in_array($campoRequerido, $campos)) { $valido = false; } } }

01

2

01

2

Page 15: Object Calisthenics: relaxe e escreva códigos simples

15

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO I somente um nível de identação/recuo por método

public function validarProdutos($produtos) { $camposRequeridos = array( 'nome', 'preco', 'descricao', 'tipo' ); foreach($produtos as $produto) { if( ! $this->validarProdutoIndividual($produto, $camposRequeridos)) { return false; } } return true; } public function validarProdutoIndividual($produto, $camposRequeridos) { $campos = array_keys($produto); $camposEsquecidos = array_diff($camposRequeridos, $campos); return (count($camposEsquecidos) == 0); }

Page 16: Object Calisthenics: relaxe e escreva códigos simples

16

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO I somente um nível de identação/recuo por método

public function validarProdutos($produtos) { $camposRequeridos = array( 'nome', 'preco', 'descricao', 'tipo' ); foreach($produtos as $produto) { if( ! $this->validarProdutoIndividual($produto, $camposRequeridos)) { return false; } } return true; } public function validarProdutoIndividual($produto, $camposRequeridos) { $campos = array_keys($produto); $camposEsquecidos = array_diff($camposRequeridos, $campos); return (count($camposEsquecidos) == 0); }

01

2

Page 17: Object Calisthenics: relaxe e escreva códigos simples

17

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO I somente um nível de identação/recuo por método

public function validarProdutos($produtos) { $produtosInvalidos = array_filter($produtos, 'verificaProdutoInvalido'); return (count($produtosInvalidos) === 0); } public function verificaProdutoInvalido($produto) { $camposRequeridos = array( 'nome', 'preco', 'descricao', 'tipo' ); $campos = array_keys($produto); $camposEsquecidos = array_diff($camposRequeridos, $campos); return (count($camposEsquecidos) > 0); }

Page 18: Object Calisthenics: relaxe e escreva códigos simples

18

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO I somente um nível de identação/recuo por método

class Board { ... String board() { StringBuffer buf = new StringBuffer(); for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { buf.append(data[i][j]); } buf.append(“\n”); } return buf.toString(); }}

Page 19: Object Calisthenics: relaxe e escreva códigos simples

19

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO I somente um nível de identação/recuo por método

class Board { ... String board() { StringBuffer buf = new StringBuffer(); for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { buf.append(data[i][j]); } buf.append(“\n”); } return buf.toString(); }}

01

2

Page 20: Object Calisthenics: relaxe e escreva códigos simples

20

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO I somente um nível de identação/recuo por método

class Board { ... String board() { StringBuffer buf = new StringBuffer(); collectRows(buf); return buf.toString(); } void collectRows(StringBuffer buf) { for (int i = 0; i < 10; i++) { collectRow(buf, i); } } void collectRow(StringBuffer buf, int row) { for (int i = 0; i < 10; i++) { Buf.append(data[row][i]); } buf.append(“\n”); }}

Page 21: Object Calisthenics: relaxe e escreva códigos simples

21

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO I somente um nível de identação/recuo por método

• Benefícios:

– Maior coesão;

– Reduz a complexidade ciclomática;

– Métodos acabam fazendo apenas uma coisa, como deve ser;

– Aumenta a reusabilidade.

Page 22: Object Calisthenics: relaxe e escreva códigos simples

22

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO II

não utilize a palavra-chave else.

Page 23: Object Calisthenics: relaxe e escreva códigos simples

23

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO II não utilize a palavra-chave else

public function login() { $usuario = $this->input()->post('usuario'); $senha = $this->input()->post('senha'); $referencia = $this->input()->post('referencia'); if($this->usuariosModel->verificaPermissao($usuario, $senha)) { redirect($referencia); } else { $this->session->setFlashData('erro', 'Usuário ou senha inválidos.'); $this->session->setFlashData('referencia', $referencia); redirect('login'); } }

Page 24: Object Calisthenics: relaxe e escreva códigos simples

24

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO II não utilize a palavra-chave else

public function login() { $usuario = $this->input()->post('usuario'); $senha = $this->input()->post('senha'); $referencia = $this->input()->post('referencia'); if($this->usuariosModel->verificaPermissao($usuario, $senha)) { redirect($referencia); } else { $this->session->setFlashData('erro', 'Usuário ou senha inválidos.'); $this->session->setFlashData('referencia', $referencia); redirect('login'); } }

Page 25: Object Calisthenics: relaxe e escreva códigos simples

25

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO II não utilize a palavra-chave else

public function login() { $usuario = $this->input()->post('usuario'); $senha = $this->input()->post('senha'); $referencia = $this->input()->post('referencia'); if( ! $this->usuariosModel->verificaPermissao($usuario, $senha)) { $this->session->setFlashData('erro', 'Usuário ou senha inválidos.'); $this->session->setFlashData('referencia', $referencia); $referencia = 'login'; }

redirect($referencia); }

Page 26: Object Calisthenics: relaxe e escreva códigos simples

26

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO II não utilize a palavra-chave else

• Benefícios:

– Ajuda a prevenir duplicação de código;

– Reduz a complexidade ciclomática;

– Faz o código ficar mais limpo, passando por um único caminho.

Page 27: Object Calisthenics: relaxe e escreva códigos simples

27

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO III

encapsule todos os tipos primitivos e strings.

Page 28: Object Calisthenics: relaxe e escreva códigos simples

28

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO III encapsule todos os tipos primitivos e strings

class Aluno { private int matricula; private boolean ativo; private long cpf; //... }

Page 29: Object Calisthenics: relaxe e escreva códigos simples

29

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO III encapsule todos os tipos primitivos e strings

class Aluno { private Integer matricula; private Boolean ativo; private Long cpf; //... }

Page 30: Object Calisthenics: relaxe e escreva códigos simples

30

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO III (ajuste)

encapsule todos os tipos primitivos e strings, se eles possuírem comportamento.

Page 31: Object Calisthenics: relaxe e escreva códigos simples

31

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO III encapsule os tipos primitivos e strings, se eles possuírem

comportamento

class UIComponent { //... public function repaint($animate = true) { //... }}//...$component->repaint(false);

Page 32: Object Calisthenics: relaxe e escreva códigos simples

32

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO III encapsule os tipos primitivos e strings, se eles possuírem

comportamento

class UIComponent { //... public function repaint(Animate $animate) { //... }}

class Animate { private $animate; public function __construct($animate = true) { $this->animate = true; }}//...$component->repaint( new Animate(false) );

Page 33: Object Calisthenics: relaxe e escreva códigos simples

33

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO III encapsule os tipos primitivos e strings, se eles possuírem

comportamento

• Benefícios:

– Indução de Tipo;

– Encapsulamento de operações.

Page 34: Object Calisthenics: relaxe e escreva códigos simples

34

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO IV

somente um ponto (“arrow” para o PHP) por linha.

Page 35: Object Calisthenics: relaxe e escreva códigos simples

35

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO IV(ajuste)

somente um ponto (“arrow” para o PHP) por linha, se não for

fluente.

Page 36: Object Calisthenics: relaxe e escreva códigos simples

36

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO IV somente um ponto por linha, se não for fluente

$filterChain->addFilter(new Zend_Filter_Alpha()) ->addFilter(new Zend_Filter_StringToLower());

listeners->addListener(new TimeListener()) ->addListener(new RestfulListener());

Não utilize:

$user->getLocation()->getCountry()->getName();

user.getAddress().getPostalConde();

$this->getRestService()->getJson($representations->find($url->getPath()));

this.getUsers().find(userId).getAddress().

Page 37: Object Calisthenics: relaxe e escreva códigos simples

37

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO IV somente um ponto por linha, se não for fluente

• Benefícios:

– Legibilidade;

– Construção de testes facilitada (mocks);

– Mais fácil para depurar;

Page 38: Object Calisthenics: relaxe e escreva códigos simples

38

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO V

não abrevie.

Page 39: Object Calisthenics: relaxe e escreva códigos simples

39

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO Vnão abrevie

• Por que você abrevia?– Preguiça de escrever o mesmo nome várias vezes...

• Talvez isso indique duplicidade de código!

– Preguiça de escrever o nome do método muito longo...• Talvez isso indique que o seu método faz mais de

uma coisa. Isso deve ser separado em vários métodos ou até classes!

Page 40: Object Calisthenics: relaxe e escreva códigos simples

40

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO Vnão abrevie

• Benefícios:

– Comunicação mais clara;

– Facilita a busca por problemas ocultos.

Page 41: Object Calisthenics: relaxe e escreva códigos simples

41

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO VI

mantenha suas entidades pequenas.

Page 42: Object Calisthenics: relaxe e escreva códigos simples

42

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO VImantenha suas entidades pequenas

• Regra original: – 50 linhas por classe.

• Regra adaptada: – 100 linhas por classe (para incluir os blocos de

documentação);– 15 classes por pacote/namespace/pasta;– De 15 a 20 linhas por método.

Page 43: Object Calisthenics: relaxe e escreva códigos simples

43

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO VImantenha suas entidades pequenas

• Benefícios:

– Responsabilidade única;

– Métodos objetivos;

– Pacotes/namespaces mais enxutos;

Page 44: Object Calisthenics: relaxe e escreva códigos simples

44

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO VII

não crie classes com mais de duas variáveis de instância.

Page 45: Object Calisthenics: relaxe e escreva códigos simples

45

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO VII(ajuste)

não crie classes com mais de cinco variáveis de instância.

Page 46: Object Calisthenics: relaxe e escreva códigos simples

46

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO VIInão crie classes com mais de cinco variáveis de instância.

• Benefícios:

– Lista reduzida de dependências;

– Mais fácil para fazer Mocking para testes.

Page 47: Object Calisthenics: relaxe e escreva códigos simples

47

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO VIII

use coleções de primeiro nível.

Page 48: Object Calisthenics: relaxe e escreva códigos simples

48

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO VIIIuse coleções de primeiro nível.

• Qualquer classe que contenha uma coleção (ou tenha esse propósito), não deve conter outras propriedades;

• Encapsulamento de coleções primitivas (arrays);

• Utilização de Interfaces Orientadas a Objetos:– Collections do Java;– SPL do PHP.

Page 49: Object Calisthenics: relaxe e escreva códigos simples

49

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO VIIIuse coleções de primeiro nível.

• Benefícios:

– É possível implementar operações em coleções;

– Utilizar métodos já existentes em interfaces pré-definidas;

Page 50: Object Calisthenics: relaxe e escreva códigos simples

50

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO IX

não crie métodos getter/setter para propriedades.

Page 51: Object Calisthenics: relaxe e escreva códigos simples

51

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO IX(removida)

não crie métodos getter/setter para propriedades.

Page 52: Object Calisthenics: relaxe e escreva códigos simples

52

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO IXcrie métodos getter/setter para propriedades

• Muitos frameworks utilizam os métodos getters e setters para inicializar variáveis, reduzindo código e evitando erros desnecessários.

• Não coloque nenhum tipo de regra de negócio nos getters e setters.

Page 53: Object Calisthenics: relaxe e escreva códigos simples

53

Object Calisthenics: relaxe e escreva códigos simples

ORIENTAÇÃO X (bônus)

documente seu código.

Page 54: Object Calisthenics: relaxe e escreva códigos simples

54

Object Calisthenics: relaxe e escreva códigos simples

Referências

• Object Calisthenics aplicado ao PHP– Guilherme Blanco

• You code sucks, let's fix it– Rafael Dohms

• The ThoughtWorks Anthology– Martin Fower

Page 55: Object Calisthenics: relaxe e escreva códigos simples

55

Object Calisthenics: relaxe e escreva códigos simples

FIM

Perguntas?

Obrigado!

Otávio Calaça Xavier

[email protected]

@otaviocx