Object Calisthenics:
relaxe e escreva
códigos simples
Goiânia, 23 de Março de 2013
Otávio Calaça Xavier
otaviocx@gmail.com
 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
3
Object Calisthenics: relaxe e escreva códigos simples
Roteiro
• Motivação;
• Orientações;
• Aplicação.
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?
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.
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.
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.
8
Object Calisthenics: relaxe e escreva códigos simples
ORIENTAÇÃO I
somente um nível de
identação/recuo por método.
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;
}
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;
}
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
1
2
3
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;
}
}
}
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;
}
}
}
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;
}
}
}
0
1
2
0
1
2
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);
}
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);
}
0
1
2
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);
}
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();
}
}
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();
}
}
0
1
2
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”);
}
}
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.
22
Object Calisthenics: relaxe e escreva códigos simples
ORIENTAÇÃO II
não utilize a palavra-chave else.
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');
}
}
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');
}
}
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);
}
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.
27
Object Calisthenics: relaxe e escreva códigos simples
ORIENTAÇÃO III
encapsule todos os tipos
primitivos e strings.
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;
//...
}
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;
//...
}
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.
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);
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) );
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.
34
Object Calisthenics: relaxe e escreva códigos simples
ORIENTAÇÃO IV
somente um ponto (“arrow” para
o PHP) por linha.
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.
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().
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;
38
Object Calisthenics: relaxe e escreva códigos simples
ORIENTAÇÃO V
não abrevie.
39
Object Calisthenics: relaxe e escreva códigos simples
ORIENTAÇÃO V
nã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!
40
Object Calisthenics: relaxe e escreva códigos simples
ORIENTAÇÃO V
não abrevie
• Benefícios:
– Comunicação mais clara;
– Facilita a busca por problemas ocultos.
41
Object Calisthenics: relaxe e escreva códigos simples
ORIENTAÇÃO VI
mantenha suas entidades
pequenas.
42
Object Calisthenics: relaxe e escreva códigos simples
ORIENTAÇÃO VI
mantenha 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.
43
Object Calisthenics: relaxe e escreva códigos simples
ORIENTAÇÃO VI
mantenha suas entidades pequenas
• Benefícios:
– Responsabilidade única;
– Métodos objetivos;
– Pacotes/namespaces mais enxutos;
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.
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.
46
Object Calisthenics: relaxe e escreva códigos simples
ORIENTAÇÃO VII
nã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.
47
Object Calisthenics: relaxe e escreva códigos simples
ORIENTAÇÃO VIII
use coleções de primeiro nível.
48
Object Calisthenics: relaxe e escreva códigos simples
ORIENTAÇÃO VIII
use 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.
49
Object Calisthenics: relaxe e escreva códigos simples
ORIENTAÇÃO VIII
use 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;
50
Object Calisthenics: relaxe e escreva códigos simples
ORIENTAÇÃO IX
não crie métodos getter/setter
para propriedades.
51
Object Calisthenics: relaxe e escreva códigos simples
ORIENTAÇÃO IX
(removida)
não crie métodos getter/setter
para propriedades.
52
Object Calisthenics: relaxe e escreva códigos simples
ORIENTAÇÃO IX
crie 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.
53
Object Calisthenics: relaxe e escreva códigos simples
ORIENTAÇÃO X
(bônus)
documente seu código.
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
55
Object Calisthenics: relaxe e escreva códigos simples
FIM
Perguntas?
Obrigado!
Otávio Calaça Xavier
otaviocx@gmail.com
@otaviocx

Object Calisthenics: relaxe e escreva códigos simples

  • 1.
    Object Calisthenics: relaxe eescreva códigos simples Goiânia, 23 de Março de 2013 Otávio Calaça Xavier otaviocx@gmail.com
  • 2.
     Criado emdezembro 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
  • 3.
    3 Object Calisthenics: relaxee escreva códigos simples Roteiro • Motivação; • Orientações; • Aplicação.
  • 4.
    4 Object Calisthenics: relaxee 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?
  • 5.
    5 Object Calisthenics: relaxee 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.
  • 6.
    6 Object Calisthenics: relaxee 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.
  • 7.
    7 Object Calisthenics: relaxee escreva códigos simples Object Calisthenics • Orientações: – Nove (9) orientações simples e que podem ser utilizadas em qualquer linguagem orientada a objetos.
  • 8.
    8 Object Calisthenics: relaxee escreva códigos simples ORIENTAÇÃO I somente um nível de identação/recuo por método.
  • 9.
    9 Object Calisthenics: relaxee 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; }
  • 10.
    10 Object Calisthenics: relaxee 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; }
  • 11.
    11 Object Calisthenics: relaxee 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 1 2 3
  • 12.
    12 Object Calisthenics: relaxee 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; } } }
  • 13.
    13 Object Calisthenics: relaxee 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; } } }
  • 14.
    14 Object Calisthenics: relaxee 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; } } } 0 1 2 0 1 2
  • 15.
    15 Object Calisthenics: relaxee 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); }
  • 16.
    16 Object Calisthenics: relaxee 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); } 0 1 2
  • 17.
    17 Object Calisthenics: relaxee 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); }
  • 18.
    18 Object Calisthenics: relaxee 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(); } }
  • 19.
    19 Object Calisthenics: relaxee 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(); } } 0 1 2
  • 20.
    20 Object Calisthenics: relaxee 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”); } }
  • 21.
    21 Object Calisthenics: relaxee 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.
  • 22.
    22 Object Calisthenics: relaxee escreva códigos simples ORIENTAÇÃO II não utilize a palavra-chave else.
  • 23.
    23 Object Calisthenics: relaxee 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'); } }
  • 24.
    24 Object Calisthenics: relaxee 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'); } }
  • 25.
    25 Object Calisthenics: relaxee 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); }
  • 26.
    26 Object Calisthenics: relaxee 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.
  • 27.
    27 Object Calisthenics: relaxee escreva códigos simples ORIENTAÇÃO III encapsule todos os tipos primitivos e strings.
  • 28.
    28 Object Calisthenics: relaxee 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; //... }
  • 29.
    29 Object Calisthenics: relaxee 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; //... }
  • 30.
    30 Object Calisthenics: relaxee escreva códigos simples ORIENTAÇÃO III (ajuste) encapsule todos os tipos primitivos e strings, se eles possuírem comportamento.
  • 31.
    31 Object Calisthenics: relaxee 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);
  • 32.
    32 Object Calisthenics: relaxee 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) );
  • 33.
    33 Object Calisthenics: relaxee 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.
  • 34.
    34 Object Calisthenics: relaxee escreva códigos simples ORIENTAÇÃO IV somente um ponto (“arrow” para o PHP) por linha.
  • 35.
    35 Object Calisthenics: relaxee escreva códigos simples ORIENTAÇÃO IV (ajuste) somente um ponto (“arrow” para o PHP) por linha, se não for fluente.
  • 36.
    36 Object Calisthenics: relaxee 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().
  • 37.
    37 Object Calisthenics: relaxee 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;
  • 38.
    38 Object Calisthenics: relaxee escreva códigos simples ORIENTAÇÃO V não abrevie.
  • 39.
    39 Object Calisthenics: relaxee escreva códigos simples ORIENTAÇÃO V nã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!
  • 40.
    40 Object Calisthenics: relaxee escreva códigos simples ORIENTAÇÃO V não abrevie • Benefícios: – Comunicação mais clara; – Facilita a busca por problemas ocultos.
  • 41.
    41 Object Calisthenics: relaxee escreva códigos simples ORIENTAÇÃO VI mantenha suas entidades pequenas.
  • 42.
    42 Object Calisthenics: relaxee escreva códigos simples ORIENTAÇÃO VI mantenha 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.
  • 43.
    43 Object Calisthenics: relaxee escreva códigos simples ORIENTAÇÃO VI mantenha suas entidades pequenas • Benefícios: – Responsabilidade única; – Métodos objetivos; – Pacotes/namespaces mais enxutos;
  • 44.
    44 Object Calisthenics: relaxee escreva códigos simples ORIENTAÇÃO VII não crie classes com mais de duas variáveis de instância.
  • 45.
    45 Object Calisthenics: relaxee escreva códigos simples ORIENTAÇÃO VII (ajuste) não crie classes com mais de cinco variáveis de instância.
  • 46.
    46 Object Calisthenics: relaxee escreva códigos simples ORIENTAÇÃO VII nã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.
  • 47.
    47 Object Calisthenics: relaxee escreva códigos simples ORIENTAÇÃO VIII use coleções de primeiro nível.
  • 48.
    48 Object Calisthenics: relaxee escreva códigos simples ORIENTAÇÃO VIII use 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.
  • 49.
    49 Object Calisthenics: relaxee escreva códigos simples ORIENTAÇÃO VIII use 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;
  • 50.
    50 Object Calisthenics: relaxee escreva códigos simples ORIENTAÇÃO IX não crie métodos getter/setter para propriedades.
  • 51.
    51 Object Calisthenics: relaxee escreva códigos simples ORIENTAÇÃO IX (removida) não crie métodos getter/setter para propriedades.
  • 52.
    52 Object Calisthenics: relaxee escreva códigos simples ORIENTAÇÃO IX crie 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.
  • 53.
    53 Object Calisthenics: relaxee escreva códigos simples ORIENTAÇÃO X (bônus) documente seu código.
  • 54.
    54 Object Calisthenics: relaxee 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
  • 55.
    55 Object Calisthenics: relaxee escreva códigos simples FIM Perguntas? Obrigado! Otávio Calaça Xavier otaviocx@gmail.com @otaviocx