Your SlideShare is downloading. ×
0
Object Calisthenics      Applied to PHP
Object CalisthenicsThe speaker    @guilhermeblanco    http://github.com/guilhermeblanco
Object CalisthenicsAgenda‣ Motivation‣ Rules‣ Application
Object CalisthenicsErm... WTH is Object Calisthenics?‣ Object Calisthenics
Object CalisthenicsErm... WTH is Object Calisthenics?‣ Object Calisthenics     Term derived from greek,     “exercise”, un...
Object CalisthenicsErm... WTH is Object Calisthenics?‣ Jeff Bay in The ThoughtWorks                                     An...
Object CalisthenicsMotivation‣ Readable Code‣ Comprehensible‣ Testable‣ Maintainable                   Learning about good...
Object CalisthenicsRules‣ Nine (9) rules “very” simple...
Object CalisthenicsRule 1: Only one indentation level per method‣ Only one indentation level per method
Object CalisthenicsRule 1: Only one indentation level per methodpublic function validateForm($filters=, $validators=, $opt...
Object CalisthenicsRule 1: Only one indentation level per methodpublic function validateForm($filters=, $validators=, $opt...
Object CalisthenicsRule 1: Only one indentation level per methodpublic function validateForm($filters=, $validators=, $opt...
Object CalisthenicsRule 1: Only one indentation level per methodpublic function validateForm($filters = array(), $validato...
Object CalisthenicsRule 1: Only one indentation level per methodpublic function validateForm($filters = array(), $validato...
Object CalisthenicsRule 1: Only one indentation level per methodpublic function validateForm($filters = array(), $validato...
Object CalisthenicsRule 1: Only one indentation level per methodpublic function validateForm($filters = array(), $validato...
Object CalisthenicsRule 1: Only one indentation level per methodpublic function validatePost($filters = array(), $validato...
Object CalisthenicsRule 1: Only one indentation level per methodpublic function validatePost($filters = array(), $validato...
Object CalisthenicsRule 2: Do not use the “else” keyword‣ Never use the “else” keyword
Object CalisthenicsRule 2: Do not use the “else” keywordfunction login()   {    $login     =   $this->input->post(email, t...
Object CalisthenicsRule 2: Do not use the “else” keywordfunction login()   {    $login     =   $this->input->post(email, t...
Object CalisthenicsRule 2: Do not use the “else” keywordfunction login()   {    $login     =   $this->input->post(email, t...
Object CalisthenicsRule 2: Do not use the “else” keywordfunction login()   {    $login     =   $this->input->post(email, t...
Object CalisthenicsRule 3: Wrap primitive types and strings‣ Wrap all primitive types and strings
Object CalisthenicsRule 3: Wrap primitive types and strings‣ This rule cannot be completely ported to PHP, because  the la...
Object CalisthenicsRule 3: Wrap primitive types and strings‣ But... if the variable of primitive type has a behavior, it  ...
Object CalisthenicsRule 3: Wrap primitive types and stringsclass UIComponent{! // ...!    public function repaint($animate...
Object CalisthenicsRule 3: Wrap primitive types and stringsclass UIComponent{! // ...!    public function repaint($animate...
Object CalisthenicsRule 3: Wrap primitive types and stringsclass UIComponent{! // ...!    public function repaint(Animate ...
Object CalisthenicsRule 4: Only one dot per line‣ Only one dot (arrow for PHP) per line
Object CalisthenicsRule 4: Only one dot per line‣ Not applicable to PHP...
Object CalisthenicsRule 4: Only one dot per line‣ ...but multiple nested calls...   ‣ tend to expose an encapsulation prob...
Object CalisthenicsRule 4: Only one dot per line‣ We could adapt to the language, contemplating...
Object CalisthenicsRule 4: Only one dot per line‣ A chain of different objects, but only if the execution  only includes g...
Object CalisthenicsRule 4: Only one dot per line‣ A chain of a unique object, through the usage of a  fluent interface     ...
Object CalisthenicsRule 5: Do not abbreviate‣ Do not abbreviate
Object CalisthenicsRule 5: Do not abbreviate
Object CalisthenicsRule 5: Do not abbreviate‣ Think about it... why do you want to abbreviate?
Object CalisthenicsRule 5: Do not abbreviate‣ Think about it... why do you want to abbreviate?   ‣ Write the same name rep...
Object CalisthenicsRule 5: Do not abbreviate‣ Think about it... why do you want to abbreviate?   ‣ Write the same name rep...
Object CalisthenicsRule 5: Do not abbreviate‣ Think about it... why do you want to abbreviate?   ‣ Write the same name rep...
Object CalisthenicsRule 5: Do not abbreviate‣ Think about it... why do you want to abbreviate?   ‣ Write the same name rep...
Object CalisthenicsRule 5: Do not abbreviate‣ Think about it... why do you want to abbreviate?   ‣ Write the same name rep...
Object CalisthenicsRule 6: Keep your entities small‣ Keep your entities small
Object CalisthenicsRule 6: Keep your entities small‣ Original rule: 50 lines per class
Object CalisthenicsRule 6: Keep your entities small‣ Adapted to PHP: 100 lines per class and no more than  15 classes per ...
Object CalisthenicsRule 7: Do not create classes with more than 2 instance variables‣ Do not create classes with more than...
Object CalisthenicsRule 7: Do not create classes with more than 2 instance variables‣ Objective:   ‣ Low cohesion   ‣ Bett...
Object CalisthenicsRule 7: Do not create classes with more than 2 instance variables‣ The original rule points to 2 instan...
Object CalisthenicsRule 8: Use first class collections‣ Use first class collections
Object CalisthenicsRule 8: Use first class collections‣ The rule is simple: Any class that contains a collection  (array to...
Object CalisthenicsRule 8: Use first class collections‣ Objectives:   ‣ Specific behaviors have a good place to stay   ‣ Fil...
Object CalisthenicsRule 8: Use first class collections‣ DoctrineCommonCollectionsArrayCollection   ‣ Countable   ‣ Iterator...
Object CalisthenicsRule 9: Do not create getter/setter methods to properties‣ Do not create getter/setter methods to prope...
Object CalisthenicsRule 9: Do not create getter/setter methods to properties‣ Non-applicable to PHP due to language’s nature
Object CalisthenicsRule 9: Do not create getter/setter methods to properties/**  * THIS CLASS WAS GENERATED BY THE DOCTRIN...
Object Calisthenics“Rule 10”: Document your code!‣ Document your code!!!!!!!!!!!!!!!!!
Object CalisthenicsThat’s all folks!‣ Questions?    @guilhermeblanco    http://github.com/guilhermeblanco
Upcoming SlideShare
Loading in...5
×

Object Calisthenics Applied to PHP

10,147

Published on

Presentation made at GTA meetup in 2012-02-07.

Object Calisthenics is a set of exercise rules to reach better code, maintainable, testable and readable.

Published in: Technology, Business
4 Comments
34 Likes
Statistics
Notes
  • @devnull3 Sorry, but when I published this talk, PDF and PPT version were all wrong, leading to what I consider non-comprehensible format.
    That's why I uploaded the original format I created (.key).
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • @DominicWatson Hi! During my talk explanation, I detail between slide 16 and 17 that you throw an exception. This means that having a foreach for messageList is irrelevant, and you could grab a single message right away.
    Maybe I shouldn't have updated the variable inside of initial foreach, but the idea was to reuse the same message variable.

    Hope you liked the presentation! =)
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Slide 17 changes variable $messageList to $message which confused me. Isn't it still a list of messages rather than a singular one? I'm guessing it's a mistake :P
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • pdf please. dot key files are apple only :(
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total Views
10,147
On Slideshare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
144
Comments
4
Likes
34
Embeds 0
No embeds

No notes for slide
  • \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
  • Transcript of "Object Calisthenics Applied to PHP"

    1. 1. Object Calisthenics Applied to PHP
    2. 2. Object CalisthenicsThe speaker @guilhermeblanco http://github.com/guilhermeblanco
    3. 3. Object CalisthenicsAgenda‣ Motivation‣ Rules‣ Application
    4. 4. Object CalisthenicsErm... WTH is Object Calisthenics?‣ Object Calisthenics
    5. 5. Object CalisthenicsErm... WTH is Object Calisthenics?‣ Object Calisthenics Term derived from greek, “exercise”, under the context of gymnastics.
    6. 6. Object CalisthenicsErm... WTH is Object Calisthenics?‣ Jeff Bay in The ThoughtWorks Anthology [1] coined the term Object Calisthenics in computers, as a group of exercises to Object Oriented programming.[1] The ThoughtWorks Anthology: Essays on Software Technology and Innovation
    7. 7. Object CalisthenicsMotivation‣ Readable Code‣ Comprehensible‣ Testable‣ Maintainable Learning about good code practices at Object CaIisthenics talk of @guilhermeblanco on @gtaphp
    8. 8. Object CalisthenicsRules‣ Nine (9) rules “very” simple...
    9. 9. Object CalisthenicsRule 1: Only one indentation level per method‣ Only one indentation level per method
    10. 10. Object CalisthenicsRule 1: Only one indentation level per methodpublic function validateForm($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 $field => $messageList) { foreach ($messageList as $message) { if (strpos($message, "empty")) { throw new Tss_FormException( "The field {$field} cannot be empty!", 3, javascript:history.back(); ); } else { throw new Tss_FormException( "{$message}", 3, javascript:history.back(); ); } } } } return $input;}
    11. 11. Object CalisthenicsRule 1: Only one indentation level per methodpublic function validateForm($filters=, $validators=, $options=){ $data = $_POST; $input = new Zend_Filter_Input($filters, $validators, $data, $options); $input->setDefaultEscapeFilter(new Zend_Filter_StringTrim()); 0 if ($input->hasInvalid() || $input->hasMissing()) { 1 foreach ($input->getMessages() as $field => $messageList) { 2 foreach(strpos($message, "empty")) { ($messageList as $message) { 3 if throw new Tss_FormException( 4 "The field {$field} cannot be empty!", 3, javascript:history.back(); ); } else { throw new Tss_FormException( "{$message}", 3, javascript:history.back(); ); } } } } return $input;}
    12. 12. Object CalisthenicsRule 1: Only one indentation level per methodpublic function validateForm($filters=, $validators=, $options=){ $data = $_POST; $input = new Zend_Filter_Input($filters, $validators, $data, $options); $input->setDefaultEscapeFilter(new Zend_Filter_StringTrim()); 0 if ($input->hasInvalid() || $input->hasMissing()) { 1 foreach ($input->getMessages() as $field => $messageList) { 2 foreach(strpos($message, "empty")) { ($messageList as $message) { 3 if throw new Tss_FormException( 4 "The field {$field} cannot be empty!", 3, javascript:history.back(); ); } else { throw new Tss_FormException( "{$message}", 3, javascript:history.back(); ); } } } } return $input;}
    13. 13. Object CalisthenicsRule 1: Only one indentation level per methodpublic function validateForm($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 => $messageList) { foreach ($messageList as $message) { if (strpos($message, "empty")) { throw new Tss_FormException( "The field {$field} cannot be empty!", 3, javascript:history.back(); ); } else { throw new Tss_FormException( "{$message}", 3, javascript:history.back(); ); } } }}
    14. 14. Object CalisthenicsRule 1: Only one indentation level per methodpublic function validateForm($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 ($input->getMessages() as $field => $messageList) { 1 foreach(strpos($message, "empty")) { ($messageList as $message) { 2 if throw new Tss_FormException( 3 "The field {$field} cannot be empty!", 3, javascript:history.back(); ); } else { throw new Tss_FormException( "{$message}", 3, javascript:history.back(); ); } } }}
    15. 15. Object CalisthenicsRule 1: Only one indentation level per methodpublic function validateForm($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 => $messageList) { foreach ($messageList as $message) { $errorMessage = (strpos($message, "empty") === false) ? "The field {$field} cannot be empty!" : "{$message}"; throw new Tss_FormException( $errorMessage, 3, javascript:history.back(); ); } }}
    16. 16. Object CalisthenicsRule 1: Only one indentation level per methodpublic function validateForm($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 ($input->getMessages() as $field => $messageList) { 1 foreach ($messageList as $message) { "empty") === false) 2 $errorMessage = (strpos($message,be empty!" ? "The field {$field} cannot : "{$message}"; throw new Tss_FormException( $errorMessage, 3, javascript:history.back(); ); } }}
    17. 17. Object CalisthenicsRule 1: Only one indentation level per methodpublic 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) ? "The field {$field} cannot be empty!" : "{$message}"; throw new Tss_FormException( $errorMessage, 3, javascript:history.back(); ); }}
    18. 18. Object CalisthenicsRule 1: Only one indentation level per methodpublic 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) ? "The field {$field} cannot be empty!" : "{$message}"; throw new Tss_FormException( $errorMessage, 3, javascript:history.back(); ); }}
    19. 19. Object CalisthenicsRule 2: Do not use the “else” keyword‣ Never use the “else” keyword
    20. 20. Object CalisthenicsRule 2: Do not use the “else” keywordfunction login() { $login = $this->input->post(email, true); $password = $this->input->post(password, true); $reference = $this->input->post(reference, true); if ($this->clients_model->login($login, $password)) { redirect($reference); } else { $this->session->set_flashdata(error, User or password invalid.); $this->session->set_flashdata(reference, $reference); redirect(clients); }}
    21. 21. Object CalisthenicsRule 2: Do not use the “else” keywordfunction login() { $login = $this->input->post(email, true); $password = $this->input->post(password, true); $reference = $this->input->post(reference, true); if ($this->clients_model->login($login, $password)) { redirect($reference); } else { $this->session->set_flashdata(error, User or password invalid.); $this->session->set_flashdata(reference, $reference); redirect(clients); }}
    22. 22. Object CalisthenicsRule 2: Do not use the “else” keywordfunction login() { $login = $this->input->post(email, true); $password = $this->input->post(password, true); $reference = $this->input->post(reference, true); if ($this->clients_model->login($login, $password)) { redirect($reference); } else { $this->session->set_flashdata(error, User or password invalid.); $this->session->set_flashdata(reference, $reference); redirect(clients); }}
    23. 23. Object CalisthenicsRule 2: Do not use the “else” keywordfunction login() { $login = $this->input->post(email, true); $password = $this->input->post(password, true); $reference = $this->input->post(reference, true); if ( ! ($this->clients_model->login($login, $password))) { $this->session->set_flashdata(error, User or password invalid.); $this->session->set_flashdata(reference, $reference); $reference = clients; } redirect($reference);}
    24. 24. Object CalisthenicsRule 3: Wrap primitive types and strings‣ Wrap all primitive types and strings
    25. 25. Object CalisthenicsRule 3: Wrap primitive types and strings‣ This rule cannot be completely ported to PHP, because the language does not perform well with an entirely Object Oriented code with a huge amount of instances
    26. 26. Object CalisthenicsRule 3: Wrap primitive types and strings‣ But... if the variable of primitive type has a behavior, it must be encapsulated
    27. 27. Object CalisthenicsRule 3: Wrap primitive types and stringsclass UIComponent{! // ...! public function repaint($animate = true) { // ... }}// ...$component->repaint(false);
    28. 28. Object CalisthenicsRule 3: Wrap primitive types and stringsclass UIComponent{! // ...! public function repaint($animate = true) { // ... }}// ...$component->repaint(false);
    29. 29. Object CalisthenicsRule 3: Wrap primitive types and stringsclass UIComponent{! // ...! public function repaint(Animate $animate) { // ... }}class Animate{ public $animate; public function __construct($animate = true) { $this->animate = $animate; }}// ...$component->repaint(new Animate(false));
    30. 30. Object CalisthenicsRule 4: Only one dot per line‣ Only one dot (arrow for PHP) per line
    31. 31. Object CalisthenicsRule 4: Only one dot per line‣ Not applicable to PHP...
    32. 32. Object CalisthenicsRule 4: Only one dot per line‣ ...but multiple nested calls... ‣ tend to expose an encapsulation problem ‣ increase difficulty to debug and exception handling ‣ do not represent an atomic action
    33. 33. Object CalisthenicsRule 4: Only one dot per line‣ We could adapt to the language, contemplating...
    34. 34. Object CalisthenicsRule 4: Only one dot per line‣ A chain of different objects, but only if the execution only includes getters and setters $user->getLocationPoint()->getCountry()->getName();
    35. 35. Object CalisthenicsRule 4: Only one dot per line‣ A chain of a unique object, through the usage of a fluent interface $filterChain->addFilter(new Zend_Filter_Alpha()) ->addFilter(new Zend_Filter_StringToLower());
    36. 36. Object CalisthenicsRule 5: Do not abbreviate‣ Do not abbreviate
    37. 37. Object CalisthenicsRule 5: Do not abbreviate
    38. 38. Object CalisthenicsRule 5: Do not abbreviate‣ Think about it... why do you want to abbreviate?
    39. 39. Object CalisthenicsRule 5: Do not abbreviate‣ Think about it... why do you want to abbreviate? ‣ Write the same name repeatedly?
    40. 40. Object CalisthenicsRule 5: Do not abbreviate‣ Think about it... why do you want to abbreviate? ‣ Write the same name repeatedly? ‣ Then your method is reused multiple times, signalling a code duplication.
    41. 41. Object CalisthenicsRule 5: Do not abbreviate‣ Think about it... why do you want to abbreviate? ‣ Write the same name repeatedly? ‣ Then your method is reused multiple times, signalling a code duplication. ‣ Method name too long?
    42. 42. Object CalisthenicsRule 5: Do not abbreviate‣ Think about it... why do you want to abbreviate? ‣ Write the same name repeatedly? ‣ Then your method is reused multiple times, signalling a code duplication. ‣ Method name too long? ‣ Maybe your class has multiple responsibilities or it is missing a helper class (bad architecture).
    43. 43. Object CalisthenicsRule 5: Do not abbreviate‣ Think about it... why do you want to abbreviate? ‣ Write the same name repeatedly? ‣ Then your method is reused multiple times, signalling a code duplication. ‣ Method name too long? ‣ Maybe your class has multiple responsibilities or it is missing a helper class (bad architecture).
    44. 44. Object CalisthenicsRule 6: Keep your entities small‣ Keep your entities small
    45. 45. Object CalisthenicsRule 6: Keep your entities small‣ Original rule: 50 lines per class
    46. 46. Object CalisthenicsRule 6: Keep your entities small‣ Adapted to PHP: 100 lines per class and no more than 15 classes per package.‣ The change is necessary because of the lack of rule for documentation, which can easily occupy up to 50% of the lines of a class.
    47. 47. Object CalisthenicsRule 7: Do not create classes with more than 2 instance variables‣ Do not create classes with more than 2 instance variables
    48. 48. Object CalisthenicsRule 7: Do not create classes with more than 2 instance variables‣ Objective: ‣ Low cohesion ‣ Better encapsulation
    49. 49. Object CalisthenicsRule 7: Do not create classes with more than 2 instance variables‣ The original rule points to 2 instance variables‣ To PHP, the suggestion is no more than 5 variables
    50. 50. Object CalisthenicsRule 8: Use first class collections‣ Use first class collections
    51. 51. Object CalisthenicsRule 8: Use first class collections‣ The rule is simple: Any class that contains a collection (array to PHP), cannot contain any other properties
    52. 52. Object CalisthenicsRule 8: Use first class collections‣ Objectives: ‣ Specific behaviors have a good place to stay ‣ Filtering, combining, mapping, ...
    53. 53. Object CalisthenicsRule 8: Use first class collections‣ DoctrineCommonCollectionsArrayCollection ‣ Countable ‣ IteratorAggregate (inherits Traversable) ‣ ArrayAccess
    54. 54. Object CalisthenicsRule 9: Do not create getter/setter methods to properties‣ Do not create getter/setter methods to properties
    55. 55. Object CalisthenicsRule 9: Do not create getter/setter methods to properties‣ Non-applicable to PHP due to language’s nature
    56. 56. Object CalisthenicsRule 9: Do not create getter/setter methods to properties/** * 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); } // ...}
    57. 57. Object Calisthenics“Rule 10”: Document your code!‣ Document your code!!!!!!!!!!!!!!!!!
    58. 58. Object CalisthenicsThat’s all folks!‣ Questions? @guilhermeblanco http://github.com/guilhermeblanco
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×