PHPubSP Object Calisthenics aplicado ao PHP
Upcoming SlideShare
Loading in...5
×
 

PHPubSP Object Calisthenics aplicado ao PHP

on

  • 5,031 views

Apresentação ministrada em 27/09/2011 no Tribeca Pub em São Paulo.

Apresentação ministrada em 27/09/2011 no Tribeca Pub em São Paulo.

Object Calisthenics são exercícios que podem ser praticados com o objetivo de melhor

Statistics

Views

Total Views
5,031
Views on SlideShare
4,988
Embed Views
43

Actions

Likes
20
Downloads
66
Comments
1

7 Embeds 43

https://twitter.com 15
http://a0.twimg.com 11
http://paper.li 9
http://www.mefeedia.com 3
https://si0.twimg.com 3
http://us-w1.rockmelt.com 1
http://www.linkedin.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel

11 of 1

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

PHPubSP Object Calisthenics aplicado ao PHP PHPubSP Object Calisthenics aplicado ao PHP Presentation Transcript

  • Object Calisthenics Aplicado ao PHP
  • Object CalisthenicsO palestrante @guilhermeblanco http://github.com/guilhermeblanco
  • Object CalisthenicsAgenda‣ Motivação‣ Regras‣ Aplicação
  • Object CalisthenicsO que é Object Calisthenics?‣ Object Calisthenics
  • Object CalisthenicsO que é Object Calisthenics?‣ Object Calisthenics Termo derivado do grego “exercício”, sob o contexto de ginástica.
  • Object CalisthenicsO que é Object Calisthenics?‣ Jeff Bay em The ThoughtWorks Anthology[1] cunhou o termo Object Calisthenics para a computação, como o conjunto de exercícios para a programação Orientada a Objetos.[1] The ThoughtWorks Anthology: Essays on Software Technology and Innovation
  • Object CalisthenicsMotivação‣ Código legível‣ Compreensível‣ Testável‣ Manutenível
  • Object CalisthenicsRegras‣ Nove (9) regras “bem” simples...
  • Object CalisthenicsRegra 1: Somente um nível de indentação por método‣ Somente um nível de indentação por método
  • Object CalisthenicsRegra 1: Somente um nível de indentação por método‣ Somente um nível de indentação por método Neologismo derivado da palavra inglesa “indentatio”, que significa “recuo”.
  • Object CalisthenicsRegra 1: Somente um nível de indentação por métodopublic function validaFormulario($filters=, $validators=, $options=){ $data = $_POST; $input = new Zend_Filter_Input($filters, $validators, $data, $options); $input->setDefaultEscapeFilter(new Zend_Filter_StringTrim()); if ($input->hasInvalid() || $input->hasMissing()) { foreach ($input->getMessages() as $campo => $message) { foreach ($message as $mensagem) { if (strpos($mensagem, "empty")) { throw new Tss_FormException( "O campo {$campo} não pode ser vazio!", 3, javascript:history.back(); ); } else { throw new Tss_FormException( "{$mensagem}", 3, javascript:history.back(); ); } } } } return $input;}
  • Object CalisthenicsRegra 1: Somente um nível de indentação por métodopublic function validaFormulario($filters=, $validators=, $options=){ $data = $_POST; $input = new Zend_Filter_Input($filters, $validators, $data, $options); $input->setDefaultEscapeFilter(new Zend_Filter_StringTrim()); 0 ($input->hasInvalid() || $input->hasMissing()) { $message) { if 1 ($message as $mensagem) { foreach ($input->getMessages() as $campo => 2 3 foreach if (strpos($mensagem, "empty")) { 4 throw new Tss_FormException( "O campo {$campo} não pode ser vazio!", 3, javascript:history.back(); ); } else { throw new Tss_FormException( "{$mensagem}", 3, javascript:history.back(); ); } } } } return $input;}
  • Object CalisthenicsRegra 1: Somente um nível de indentação por métodopublic function validaFormulario($filters=, $validators=, $options=){ $data = $_POST; $input = new Zend_Filter_Input($filters, $validators, $data, $options); $input->setDefaultEscapeFilter(new Zend_Filter_StringTrim()); 0 ($input->hasInvalid() || $input->hasMissing()) { $message) { if 1 ($message as $mensagem) { foreach ($input->getMessages() as $campo => 2 3 foreach if (strpos($mensagem, "empty")) { 4 throw new Tss_FormException( "O campo {$campo} não pode ser vazio!", 3, javascript:history.back(); ); } else { throw new Tss_FormException( "{$mensagem}", 3, javascript:history.back(); ); } } } } return $input;}
  • Object CalisthenicsRegra 1: Somente um nível de indentação por métodopublic function validaFormulario($filters = array(), $validators = array(), $options = null){ $data = $_POST; $input = new Zend_Filter_Input($filters, $validators, $data, $options); $input->setDefaultEscapeFilter(new Zend_Filter_StringTrim()); if ( ! ($input->hasInvalid() || $input->hasMissing())) { return $input; } foreach ($input->getMessages() as $campo => $message) { foreach ($message as $mensagem) { if (strpos($mensagem, "empty")) { throw new Tss_FormException( "O campo {$campo} não pode ser vazio!", 3, javascript:history.back(); ); } else { throw new Tss_FormException( "{$mensagem}", 3, javascript:history.back(); ); } } }}
  • Object CalisthenicsRegra 1: Somente um nível de indentação por métodopublic function validaFormulario($filters = array(), $validators = array(), $options = null){ $data = $_POST; $input = new Zend_Filter_Input($filters, $validators, $data, $options); $input->setDefaultEscapeFilter(new Zend_Filter_StringTrim()); if ( ! ($input->hasInvalid() || $input->hasMissing())) { return $input; } 0 foreach ($message as $mensagem) { => $message) { foreach ($input->getMessages() as $campo 1 (strpos($mensagem, "empty")) { if 2 3 throw new Tss_FormException( "O campo {$campo} não pode ser vazio!", 3, javascript:history.back(); ); } else { throw new Tss_FormException( "{$mensagem}", 3, javascript:history.back(); ); } } }}
  • Object CalisthenicsRegra 1: Somente um nível de indentação por métodopublic function validaFormulario($filters = array(), $validators = array(), $options = null){ $data = $_POST; $input = new Zend_Filter_Input($filters, $validators, $data, $options); $input->setDefaultEscapeFilter(new Zend_Filter_StringTrim()); if ( ! ($input->hasInvalid() || $input->hasMissing())) { return $input; } foreach ($input->getMessages() as $campo => $message) { foreach ($message as $mensagem) { $errorMessage = (strpos($mensagem, "empty") === false) ? "O campo {$campo} não pode ser vazio!" : "{$mensagem}"; throw new Tss_FormException( $errorMessage, 3, javascript:history.back(); ); } }}
  • Object CalisthenicsRegra 1: Somente um nível de indentação por métodopublic function validaFormulario($filters = array(), $validators = array(), $options = null){ $data = $_POST; $input = new Zend_Filter_Input($filters, $validators, $data, $options); $input->setDefaultEscapeFilter(new Zend_Filter_StringTrim()); if ( ! ($input->hasInvalid() || $input->hasMissing())) { return $input; } 0 foreach ($message as $mensagem) { => $message) { foreach ($input->getMessages() as $campo 1 2 $errorMessage = (strpos($mensagem, "empty") === false) ? "O campo {$campo} não pode ser vazio!" : "{$mensagem}"; throw new Tss_FormException( $errorMessage, 3, javascript:history.back(); ); } }}
  • Object CalisthenicsRegra 1: Somente um nível de indentação por métodopublic function validatePost($filters = array(), $validators = array(), $options = null){ $data = $_POST; $input = new Zend_Filter_Input($filters, $validators, $data, $options); $input->setDefaultEscapeFilter(new Zend_Filter_StringTrim()); if ( ! ($input->hasInvalid() || $input->hasMissing())) { return $input; } foreach ($input->getMessages() as $field => $message) { $messageKey = key($message); $message = $message[$messageKey]; $errorMessage = (strpos($message, "empty") === false) ? "O campo {$field} não pode ser vazio!" : "{$mensagem}"; throw new Tss_FormException( $errorMessage, 3, javascript:history.back(); ); }}
  • Object CalisthenicsRegra 1: Somente um nível de indentação por métodopublic function validatePost($filters = array(), $validators = array(), $options = null){ $data = $_POST; $input = new Zend_Filter_Input($filters, $validators, $data, $options); $input->setDefaultEscapeFilter(new Zend_Filter_StringTrim()); if ( ! ($input->hasInvalid() || $input->hasMissing())) { return $input; } foreach ($input->getMessages() as $field => $message) { $messageKey = key($message); $message = $message[$messageKey]; $errorMessage = (strpos($message, "empty") === false) ? "O campo {$field} não pode ser vazio!" : "{$mensagem}"; throw new Tss_FormException( $errorMessage, 3, javascript:history.back(); ); }}
  • Object CalisthenicsRegra 2: Não use a palavra-chave “else”‣ Não use a palavra-chave “else”
  • Object CalisthenicsRegra 2: Não use a palavra-chave “else”function login() { $login = $this->input->post(email, true); $password = $this->input->post(password, true); $referencia = $this->input->post(referencia, true); if ($this->clientes_model->login($login, $password)) { redirect($referencia); } else { $this->session->set_flashdata(erro, Usuário ou senha inválidos.); $this->session->set_flashdata(referencia, $referencia); redirect(clientes); }}
  • Object CalisthenicsRegra 2: Não use a palavra-chave “else”function login() { $login = $this->input->post(email, true); $password = $this->input->post(password, true); $referencia = $this->input->post(referencia, true); if ($this->clientes_model->login($login, $password)) { redirect($referencia); } else { $this->session->set_flashdata(erro, Usuário ou senha inválidos.); $this->session->set_flashdata(referencia, $referencia); redirect(clientes); }}
  • Object CalisthenicsRegra 2: Não use a palavra-chave “else”function login() { $login = $this->input->post(email, true); $password = $this->input->post(password, true); $referencia = $this->input->post(referencia, true); if ($this->clientes_model->login($login, $password)) { redirect($referencia); } else { $this->session->set_flashdata(erro, Usuário ou senha inválidos.); $this->session->set_flashdata(referencia, $referencia); redirect(clientes); }}
  • Object CalisthenicsRegra 2: Não use a palavra-chave “else”function login() { $login = $this->input->post(email, true); $password = $this->input->post(password, true); $referencia = $this->input->post(referencia, true); if ( ! ($this->clientes_model->login($login, $password))) { $this->session->set_flashdata(erro, Usuário ou senha inválidos.); $this->session->set_flashdata(referencia, $referencia); $referencia = clientes; } redirect($referencia);}
  • Object CalisthenicsRegra 3: Encapsule todos os tipos primitivos e strings‣ Encapsule todos os tipos primitivos e strings
  • Object CalisthenicsRegra 3: Encapsule todos os tipos primitivos e strings‣ Esta regra não pode ser completamente portada ao PHP, pois a linguagem não possui boa performance com um código completamente Orientado a Objetos
  • Object CalisthenicsRegra 3: Encapsule todos os tipos primitivos e strings‣ Sugestivamente, se a variável de tipo primitivo possui comportamento, ela deve ser encapsulada
  • Object CalisthenicsRegra 3: Encapsule todos os tipos primitivos e stringsclass UIComponent{ // ... public function repaint($animate = true) { // ... }}// ...$component->repaint(false);
  • Object CalisthenicsRegra 3: Encapsule todos os tipos primitivos e stringsclass UIComponent{ // ... public function repaint($animate = true) { // ... }}// ...$component->repaint(false);
  • Object CalisthenicsRegra 3: Encapsule todos os tipos primitivos e stringsclass UIComponent{ // ... public function repaint(Animate $animate = null) { // ... }}class Animate{ public $animate = true; public function __construct($animate) { $this->animate = $animate; }}// ...$component->repaint(new Animate(false));
  • Object CalisthenicsRegra 4: Somente um ponto por linha‣ Somente um ponto (“arrow” para PHP) por linha
  • Object Calisthenics‣ Não aplicável ao PHP...
  • Object CalisthenicsRegra 4: Somente um ponto por linha‣ ...mas múltiplas chamadas aninhadas... ‣ tendem a expor um problema de encapsulamento ‣ dificultam o debug ou tratamento de exceção ‣ não simbolizam uma ação atômica
  • Object CalisthenicsRegra 4: Somente um ponto por linha‣ Podemos adaptar à linguagem, contemplando...
  • Object CalisthenicsRegra 4: Somente um ponto por linha‣ Um chain de objetos diferentes, desde que a execução só inclua getters e setters $user->getLocationPoint()->getCountry()->getName();
  • Object CalisthenicsRegra 4: Somente um ponto por linha‣ Um chain do próprio objeto através de uma interface fluente $filterChain->addFilter(new Zend_Filter_Alpha()) ->addFilter(new Zend_Filter_StringToLower());
  • Object CalisthenicsRegra 5: Não abrevie‣ Não abrevie
  • Object CalisthenicsRegra 5: Não abrevie
  • Object CalisthenicsRegra 5: Não abrevie‣ Pense... por que não quer abreviar?
  • Object CalisthenicsRegra 5: Não abrevie‣ Pense... por que não quer abreviar? ‣ Escrever o mesmo nome repetidamente?
  • Object CalisthenicsRegra 5: Não abrevie‣ Pense... por que não quer abreviar? ‣ Escrever o mesmo nome repetidamente? ‣ Então seu método é reutilizado muitas vezes, sinalizando duplicidade de código.
  • Object CalisthenicsRegra 5: Não abrevie‣ Pense... por que não quer abreviar? ‣ Escrever o mesmo nome repetidamente? ‣ Então seu método é reutilizado muitas vezes, sinalizando duplicidade de código. ‣ Nome do método muito longo?
  • Object CalisthenicsRegra 5: Não abrevie‣ Pense... por que não quer abreviar? ‣ Escrever o mesmo nome repetidamente? ‣ Então seu método é reutilizado muitas vezes, sinalizando duplicidade de código. ‣ Nome do método muito longo? ‣ Sinal de uma classe com múltiplas responsabilidades ou a falta de uma classe auxiliar
  • Object CalisthenicsRegra 5: Não abrevie‣ Pense... por que não quer abreviar? ‣ Escrever o mesmo nome repetidamente? ‣ Então seu método é reutilizado muitas vezes, sinalizando duplicidade de código. ‣ Nome do método muito longo? ‣ Sinal de uma classe com múltiplas responsabilidades ou a falta de uma classe auxiliar
  • Object CalisthenicsRegra 6: Mantenha suas entidades pequenas‣ Mantenha suas entidades pequenas
  • Object CalisthenicsRegra 6: Mantenha suas entidades pequenas‣ Regra original: 50 linhas por classe
  • Object CalisthenicsRegra 6: Mantenha suas entidades pequenas‣ Adaptado ao PHP: 100 linhas por classe e não mais de 15 classes por pacote.‣ A mudança se deve ao fato que não há regra quando à documentação, que pode ocupar até 50% das linhas.
  • Object CalisthenicsRegra 7: Não crie classes com mais de duas variáveis de instância‣ Não crie classes com mais de duas variáveis de instância
  • Object CalisthenicsRegra 7: Não crie classes com mais de duas variáveis de instância‣ Objetivo: ‣ Baixa coesão ‣ Melhor encapsulamento
  • Object CalisthenicsRegra 7: Não crie classes com mais de duas variáveis de instância‣ A regra original aponta 2 variáveis de instância‣ Para o PHP, a sugestão são 5 variáveis de instância
  • Object CalisthenicsRegra 8: Use coleções de primeiro nível‣ Use coleções de primeiro nível
  • Object CalisthenicsRegra 8: Use coleções de primeiro nível‣ A regra é bem simples: Qualquer classe que contenha uma coleção (array para o PHP), não deve conter outras propriedades
  • Object CalisthenicsRegra 8: Use coleções de primeiro nível‣ Objetivo: ‣ Comportamentos específicos tem um local adequado ‣ Filtragem, combinação, mapear, ...
  • Object CalisthenicsRegra 8: Use coleções de primeiro nível‣ DoctrineCommonCollectionsArrayCollection ‣ Countable ‣ IteratorAggregate (herda Traversable) ‣ ArrayAccess
  • Object CalisthenicsRegra 9: Não crie métodos getter/setter para propriedades‣ Não crie métodos getter/setter para propriedades
  • Object CalisthenicsRegra 9: Não crie métodos getter/setter para propriedades‣ Não aplicável ao PHP devido à natureza da linguagem
  • Object CalisthenicsRegra 9: Não crie métodos getter/setter para propriedades/** * THIS CLASS WAS GENERATED BY THE DOCTRINE ORM. DO NOT EDIT THIS FILE. */class ApplicationCoreDomainUserModelUserProxy extends ApplicationCoreDomainUserModelUser implements DoctrineORMProxyProxy{ // ... public function getId() { $this->__load(); return parent::getId(); } public function setId($id) { $this->__load(); return parent::setId($id); } // ...}
  • Object Calisthenics“Regra 10”: Documente seu código!‣ Documente seu código!!!!!!!!!!!!!!!!!!!!!!
  • Object CalisthenicsThat’s all folks!‣ Perguntas? @guilhermeblanco http://github.com/guilhermeblanco