Anúncio

PHPubSP Object Calisthenics aplicado ao PHP

Team Leader em InstaClick Inc.
28 de Sep de 2011
Anúncio

Mais conteúdo relacionado

Anúncio

Último(20)

Anúncio

PHPubSP Object Calisthenics aplicado ao PHP

  1. Object Calisthenics Aplicado ao PHP
  2. Object Calisthenics O palestrante @guilhermeblanco http://github.com/guilhermeblanco
  3. Object Calisthenics Agenda ‣ Motivação ‣ Regras ‣ Aplicação
  4. Object Calisthenics O que é Object Calisthenics? ‣ Object Calisthenics
  5. Object Calisthenics O que é Object Calisthenics? ‣ Object Calisthenics Termo derivado do grego “exercício”, sob o contexto de ginástica.
  6. Object Calisthenics O 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
  7. Object Calisthenics Motivação ‣ Código legível ‣ Compreensível ‣ Testável ‣ Manutenível
  8. Object Calisthenics Regras ‣ Nove (9) regras “bem” simples...
  9. Object Calisthenics Regra 1: Somente um nível de indentação por método ‣ Somente um nível de indentação por método
  10. Object Calisthenics Regra 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”.
  11. Object Calisthenics Regra 1: Somente um nível de indentação por método public 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; }
  12. Object Calisthenics Regra 1: Somente um nível de indentação por método public 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; }
  13. Object Calisthenics Regra 1: Somente um nível de indentação por método public 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; }
  14. Object Calisthenics Regra 1: Somente um nível de indentação por método public 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();' ); } } } }
  15. Object Calisthenics Regra 1: Somente um nível de indentação por método public 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();' ); } } } }
  16. Object Calisthenics Regra 1: Somente um nível de indentação por método public 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();' ); } } }
  17. Object Calisthenics Regra 1: Somente um nível de indentação por método public 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();' ); } } }
  18. Object Calisthenics Regra 1: Somente um nível de indentação por método public 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();' ); } }
  19. Object Calisthenics Regra 1: Somente um nível de indentação por método public 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();' ); } }
  20. Object Calisthenics Regra 2: Não use a palavra-chave “else” ‣ Não use a palavra-chave “else”
  21. Object Calisthenics Regra 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'); } }
  22. Object Calisthenics Regra 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'); } }
  23. Object Calisthenics Regra 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'); } }
  24. Object Calisthenics Regra 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); }
  25. Object Calisthenics Regra 3: Encapsule todos os tipos primitivos e strings ‣ Encapsule todos os tipos primitivos e strings
  26. Object Calisthenics Regra 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
  27. Object Calisthenics Regra 3: Encapsule todos os tipos primitivos e strings ‣ Sugestivamente, se a variável de tipo primitivo possui comportamento, ela deve ser encapsulada
  28. Object Calisthenics Regra 3: Encapsule todos os tipos primitivos e strings class UIComponent { // ... public function repaint($animate = true) { // ... } } // ... $component->repaint(false);
  29. Object Calisthenics Regra 3: Encapsule todos os tipos primitivos e strings class UIComponent { // ... public function repaint($animate = true) { // ... } } // ... $component->repaint(false);
  30. Object Calisthenics Regra 3: Encapsule todos os tipos primitivos e strings class UIComponent { // ... public function repaint(Animate $animate = null) { // ... } } class Animate { public $animate = true; public function __construct($animate) { $this->animate = $animate; } } // ... $component->repaint(new Animate(false));
  31. Object Calisthenics Regra 4: Somente um ponto por linha ‣ Somente um ponto (“arrow” para PHP) por linha
  32. Object Calisthenics ‣ Não aplicável ao PHP...
  33. Object Calisthenics Regra 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
  34. Object Calisthenics Regra 4: Somente um ponto por linha ‣ Podemos adaptar à linguagem, contemplando...
  35. Object Calisthenics Regra 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();
  36. Object Calisthenics Regra 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());
  37. Object Calisthenics Regra 5: Não abrevie ‣ Não abrevie
  38. Object Calisthenics Regra 5: Não abrevie
  39. Object Calisthenics Regra 5: Não abrevie ‣ Pense... por que não quer abreviar?
  40. Object Calisthenics Regra 5: Não abrevie ‣ Pense... por que não quer abreviar? ‣ Escrever o mesmo nome repetidamente?
  41. Object Calisthenics Regra 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.
  42. Object Calisthenics Regra 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?
  43. Object Calisthenics Regra 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
  44. Object Calisthenics Regra 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
  45. Object Calisthenics Regra 6: Mantenha suas entidades pequenas ‣ Mantenha suas entidades pequenas
  46. Object Calisthenics Regra 6: Mantenha suas entidades pequenas ‣ Regra original: 50 linhas por classe
  47. Object Calisthenics Regra 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.
  48. Object Calisthenics Regra 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
  49. Object Calisthenics Regra 7: Não crie classes com mais de duas variáveis de instância ‣ Objetivo: ‣ Baixa coesão ‣ Melhor encapsulamento
  50. Object Calisthenics Regra 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
  51. Object Calisthenics Regra 8: Use coleções de primeiro nível ‣ Use coleções de primeiro nível
  52. Object Calisthenics Regra 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
  53. Object Calisthenics Regra 8: Use coleções de primeiro nível ‣ Objetivo: ‣ Comportamentos específicos tem um local adequado ‣ Filtragem, combinação, mapear, ...
  54. Object Calisthenics Regra 8: Use coleções de primeiro nível ‣ DoctrineCommonCollectionsArrayCollection ‣ Countable ‣ IteratorAggregate (herda Traversable) ‣ ArrayAccess
  55. Object Calisthenics Regra 9: Não crie métodos getter/setter para propriedades ‣ Não crie métodos getter/setter para propriedades
  56. Object Calisthenics Regra 9: Não crie métodos getter/setter para propriedades ‣ Não aplicável ao PHP devido à natureza da linguagem
  57. Object Calisthenics Regra 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); } // ... }
  58. Object Calisthenics “Regra 10”: Documente seu código! ‣ Documente seu código!!!!!!!!!!!!!!!!!!!!!!
  59. Object Calisthenics That’s all folks! ‣ Perguntas? @guilhermeblanco http://github.com/guilhermeblanco

Notas do Editor

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
Anúncio