SlideShare a Scribd company logo
1 of 58
Object Calisthenics
      Applied to PHP
Object Calisthenics
The speaker




    @guilhermeblanco

    http://github.com/guilhermeblanco
Object Calisthenics
Agenda




‣ Motivation
‣ Rules
‣ Application
Object Calisthenics
Erm... WTH is Object Calisthenics?




‣ Object Calisthenics
Object Calisthenics
Erm... WTH is Object Calisthenics?




‣ Object Calisthenics

     Term derived from greek,
     “exercise”, under the
     context of gymnastics.
Object Calisthenics
Erm... 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
Object Calisthenics
Motivation




‣ Readable Code
‣ Comprehensible
‣ Testable
‣ Maintainable
                   Learning about good code practices
                      at Object CaIisthenics talk of
                     @guilhermeblanco on @gtaphp
Object Calisthenics
Rules




‣ Nine (9) rules “very” simple...
Object Calisthenics
Rule 1: Only one indentation level per method




‣ Only one indentation level per method
Object Calisthenics
Rule 1: Only one indentation level per method
public 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;
}
Object Calisthenics
Rule 1: Only one indentation level per method
public 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;
}
Object Calisthenics
Rule 1: Only one indentation level per method
public 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;
}
Object Calisthenics
Rule 1: Only one indentation level per method
public 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();'
                );
            }
        }
    }
}
Object Calisthenics
Rule 1: Only one indentation level per method
public 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();'
                );
            }
        }
    }
}
Object Calisthenics
Rule 1: Only one indentation level per method
public 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();'
            );
        }
    }
}
Object Calisthenics
Rule 1: Only one indentation level per method
public 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();'
            );
        }
    }
}
Object Calisthenics
Rule 1: Only one indentation level per method
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)
            ? "The field {$field} cannot be empty!"
            : "{$message}";

        throw new Tss_FormException(
            $errorMessage, 3, 'javascript:history.back();'
        );
    }
}
Object Calisthenics
Rule 1: Only one indentation level per method
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)
            ? "The field {$field} cannot be empty!"
            : "{$message}";

        throw new Tss_FormException(
            $errorMessage, 3, 'javascript:history.back();'
        );
    }
}
Object Calisthenics
Rule 2: Do not use the “else” keyword




‣ Never use the “else” keyword
Object Calisthenics
Rule 2: Do not use the “else” keyword
function 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');
    }
}
Object Calisthenics
Rule 2: Do not use the “else” keyword
function 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');
    }
}
Object Calisthenics
Rule 2: Do not use the “else” keyword
function 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');
    }
}
Object Calisthenics
Rule 2: Do not use the “else” keyword
function 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);
}
Object Calisthenics
Rule 3: Wrap primitive types and strings




‣ Wrap all primitive types and strings
Object Calisthenics
Rule 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
Object Calisthenics
Rule 3: Wrap primitive types and strings




‣ But... if the variable of primitive type has a behavior, it
  must be encapsulated
Object Calisthenics
Rule 3: Wrap primitive types and strings
class UIComponent
{
! // ...
!
    public function repaint($animate = true)
    {
        // ...
    }
}

// ...
$component->repaint(false);
Object Calisthenics
Rule 3: Wrap primitive types and strings
class UIComponent
{
! // ...
!
    public function repaint($animate = true)
    {
        // ...
    }
}

// ...
$component->repaint(false);
Object Calisthenics
Rule 3: Wrap primitive types and strings
class UIComponent
{
! // ...
!
    public function repaint(Animate $animate)
    {
        // ...
    }
}

class Animate
{
    public $animate;

    public function __construct($animate = true)
    {
        $this->animate = $animate;
    }
}

// ...
$component->repaint(new Animate(false));
Object Calisthenics
Rule 4: Only one dot per line




‣ Only one dot (arrow for PHP) per line
Object Calisthenics
Rule 4: Only one dot per line




‣ Not applicable to PHP...
Object Calisthenics
Rule 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
Object Calisthenics
Rule 4: Only one dot per line




‣ We could adapt to the language, contemplating...
Object Calisthenics
Rule 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();
Object Calisthenics
Rule 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());
Object Calisthenics
Rule 5: Do not abbreviate




‣ Do not abbreviate
Object Calisthenics
Rule 5: Do not abbreviate
Object Calisthenics
Rule 5: Do not abbreviate



‣ Think about it... why do you want to abbreviate?
Object Calisthenics
Rule 5: Do not abbreviate



‣ Think about it... why do you want to abbreviate?
   ‣ Write the same name repeatedly?
Object Calisthenics
Rule 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.
Object Calisthenics
Rule 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?
Object Calisthenics
Rule 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).
Object Calisthenics
Rule 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).
Object Calisthenics
Rule 6: Keep your entities small




‣ Keep your entities small
Object Calisthenics
Rule 6: Keep your entities small




‣ Original rule: 50 lines per class
Object Calisthenics
Rule 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.
Object Calisthenics
Rule 7: Do not create classes with more than 2 instance variables




‣ Do not create classes with more than 2 instance
  variables
Object Calisthenics
Rule 7: Do not create classes with more than 2 instance variables




‣ Objective:
   ‣ Low cohesion
   ‣ Better encapsulation
Object Calisthenics
Rule 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
Object Calisthenics
Rule 8: Use first class collections




‣ Use first class collections
Object Calisthenics
Rule 8: Use first class collections




‣ The rule is simple: Any class that contains a collection
  (array to PHP), cannot contain any other properties
Object Calisthenics
Rule 8: Use first class collections




‣ Objectives:
   ‣ Specific behaviors have a good place to stay
   ‣ Filtering, combining, mapping, ...
Object Calisthenics
Rule 8: Use first class collections




‣ DoctrineCommonCollectionsArrayCollection
   ‣ Countable
   ‣ IteratorAggregate (inherits Traversable)
   ‣ ArrayAccess
Object Calisthenics
Rule 9: Do not create getter/setter methods to properties




‣ Do not create getter/setter methods to properties
Object Calisthenics
Rule 9: Do not create getter/setter methods to properties




‣ Non-applicable to PHP due to language’s nature
Object Calisthenics
Rule 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);
    }

    // ...
}
Object Calisthenics
“Rule 10”: Document your code!




‣ Document your code!!!!!!!!!!!!!!!!!
Object Calisthenics
That’s all folks!




‣ Questions?



    @guilhermeblanco

    http://github.com/guilhermeblanco

More Related Content

What's hot

Railway Oriented Programming
Railway Oriented ProgrammingRailway Oriented Programming
Railway Oriented ProgrammingScott Wlaschin
 
ES6 PPT FOR 2016
ES6 PPT FOR 2016ES6 PPT FOR 2016
ES6 PPT FOR 2016Manoj Kumar
 
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...Philip Schwarz
 
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Chris Richardson
 
ASP.NET Web API
ASP.NET Web APIASP.NET Web API
ASP.NET Web APIhabib_786
 
Back to the basics: Modelando nuestro dominio #scbcn19
Back to the basics: Modelando nuestro dominio #scbcn19Back to the basics: Modelando nuestro dominio #scbcn19
Back to the basics: Modelando nuestro dominio #scbcn19CodelyTV
 
좌충우돌 ORM 개발기 | Devon 2012
좌충우돌 ORM 개발기 | Devon 2012좌충우돌 ORM 개발기 | Devon 2012
좌충우돌 ORM 개발기 | Devon 2012Daum DNA
 
JSON Array Indexes in MySQL
JSON Array Indexes in MySQLJSON Array Indexes in MySQL
JSON Array Indexes in MySQLNorvald Ryeng
 
Threading Made Easy! A Busy Developer’s Guide to Kotlin Coroutines
Threading Made Easy! A Busy Developer’s Guide to Kotlin CoroutinesThreading Made Easy! A Busy Developer’s Guide to Kotlin Coroutines
Threading Made Easy! A Busy Developer’s Guide to Kotlin CoroutinesLauren Yew
 
Oops concepts in php
Oops concepts in phpOops concepts in php
Oops concepts in phpCPD INDIA
 

What's hot (20)

Railway Oriented Programming
Railway Oriented ProgrammingRailway Oriented Programming
Railway Oriented Programming
 
Sql query patterns, optimized
Sql query patterns, optimizedSql query patterns, optimized
Sql query patterns, optimized
 
ES6 PPT FOR 2016
ES6 PPT FOR 2016ES6 PPT FOR 2016
ES6 PPT FOR 2016
 
Laravel Tutorial PPT
Laravel Tutorial PPTLaravel Tutorial PPT
Laravel Tutorial PPT
 
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
 
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
 
Practical Object Oriented Models In Sql
Practical Object Oriented Models In SqlPractical Object Oriented Models In Sql
Practical Object Oriented Models In Sql
 
NestJS
NestJSNestJS
NestJS
 
ASP.NET Web API
ASP.NET Web APIASP.NET Web API
ASP.NET Web API
 
Sql Antipatterns Strike Back
Sql Antipatterns Strike BackSql Antipatterns Strike Back
Sql Antipatterns Strike Back
 
Back to the basics: Modelando nuestro dominio #scbcn19
Back to the basics: Modelando nuestro dominio #scbcn19Back to the basics: Modelando nuestro dominio #scbcn19
Back to the basics: Modelando nuestro dominio #scbcn19
 
좌충우돌 ORM 개발기 | Devon 2012
좌충우돌 ORM 개발기 | Devon 2012좌충우돌 ORM 개발기 | Devon 2012
좌충우돌 ORM 개발기 | Devon 2012
 
JSON Array Indexes in MySQL
JSON Array Indexes in MySQLJSON Array Indexes in MySQL
JSON Array Indexes in MySQL
 
Threading Made Easy! A Busy Developer’s Guide to Kotlin Coroutines
Threading Made Easy! A Busy Developer’s Guide to Kotlin CoroutinesThreading Made Easy! A Busy Developer’s Guide to Kotlin Coroutines
Threading Made Easy! A Busy Developer’s Guide to Kotlin Coroutines
 
Express node js
Express node jsExpress node js
Express node js
 
Java collection
Java collectionJava collection
Java collection
 
Getting started with entity framework
Getting started with entity framework Getting started with entity framework
Getting started with entity framework
 
Php Tutorials for Beginners
Php Tutorials for BeginnersPhp Tutorials for Beginners
Php Tutorials for Beginners
 
Clean code
Clean codeClean code
Clean code
 
Oops concepts in php
Oops concepts in phpOops concepts in php
Oops concepts in php
 

Similar to Object Calisthenics Applied to PHP

1st CI&T Lightning Talks: Writing better code with Object Calisthenics
1st CI&T Lightning Talks: Writing better code with Object Calisthenics1st CI&T Lightning Talks: Writing better code with Object Calisthenics
1st CI&T Lightning Talks: Writing better code with Object CalisthenicsLucas Arruda
 
Your code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConYour code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConRafael Dohms
 
TestFest - Respect\Validation 1.0
TestFest - Respect\Validation 1.0TestFest - Respect\Validation 1.0
TestFest - Respect\Validation 1.0Henrique Moody
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design PatternsHugo Hamon
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency InjectionRifat Nabi
 
Adding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy ApplicationsAdding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy ApplicationsSam Hennessy
 
The State of Lithium
The State of LithiumThe State of Lithium
The State of LithiumNate Abele
 
PHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くためにPHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くためにYuya Takeyama
 
PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2eugenio pombi
 
Crazy things done on PHP
Crazy things done on PHPCrazy things done on PHP
Crazy things done on PHPTaras Kalapun
 
Advanced php testing in action
Advanced php testing in actionAdvanced php testing in action
Advanced php testing in actionJace Ju
 
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...Mateusz Zalewski
 
Gta v savegame
Gta v savegameGta v savegame
Gta v savegamehozayfa999
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11Michelangelo van Dam
 
Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitmfrost503
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistenceHugo Hamon
 
Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitmfrost503
 

Similar to Object Calisthenics Applied to PHP (20)

1st CI&T Lightning Talks: Writing better code with Object Calisthenics
1st CI&T Lightning Talks: Writing better code with Object Calisthenics1st CI&T Lightning Talks: Writing better code with Object Calisthenics
1st CI&T Lightning Talks: Writing better code with Object Calisthenics
 
Your code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConYour code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnCon
 
TestFest - Respect\Validation 1.0
TestFest - Respect\Validation 1.0TestFest - Respect\Validation 1.0
TestFest - Respect\Validation 1.0
 
Workshop unittesting
Workshop unittestingWorkshop unittesting
Workshop unittesting
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design Patterns
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
Adding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy ApplicationsAdding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy Applications
 
The State of Lithium
The State of LithiumThe State of Lithium
The State of Lithium
 
PHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くためにPHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くために
 
PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2
 
Crazy things done on PHP
Crazy things done on PHPCrazy things done on PHP
Crazy things done on PHP
 
Advanced php testing in action
Advanced php testing in actionAdvanced php testing in action
Advanced php testing in action
 
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
 
ddd+scala
ddd+scaladdd+scala
ddd+scala
 
Gta v savegame
Gta v savegameGta v savegame
Gta v savegame
 
Drupal 8 database api
Drupal 8 database apiDrupal 8 database api
Drupal 8 database api
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnit
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
 
Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnit
 

More from Guilherme Blanco

PHP para Adultos: Clean Code e Object Calisthenics
PHP para Adultos: Clean Code e Object CalisthenicsPHP para Adultos: Clean Code e Object Calisthenics
PHP para Adultos: Clean Code e Object CalisthenicsGuilherme Blanco
 
ORM dont kill your DB, developers do
ORM dont kill your DB, developers doORM dont kill your DB, developers do
ORM dont kill your DB, developers doGuilherme Blanco
 
PHPubSP Object Calisthenics aplicado ao PHP
PHPubSP Object Calisthenics aplicado ao PHPPHPubSP Object Calisthenics aplicado ao PHP
PHPubSP Object Calisthenics aplicado ao PHPGuilherme Blanco
 
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHPIPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHPGuilherme Blanco
 
Doctrine 2.0: A evolução da persistência em PHP
Doctrine 2.0: A evolução da persistência em PHPDoctrine 2.0: A evolução da persistência em PHP
Doctrine 2.0: A evolução da persistência em PHPGuilherme Blanco
 
Doctrine 2.0 Enterprise Persistence Layer for PHP
Doctrine 2.0 Enterprise Persistence Layer for PHPDoctrine 2.0 Enterprise Persistence Layer for PHP
Doctrine 2.0 Enterprise Persistence Layer for PHPGuilherme Blanco
 
Desenvolvimento Agil Com Doctrine Orm
Desenvolvimento Agil Com Doctrine OrmDesenvolvimento Agil Com Doctrine Orm
Desenvolvimento Agil Com Doctrine OrmGuilherme Blanco
 

More from Guilherme Blanco (13)

Enterprise php
Enterprise phpEnterprise php
Enterprise php
 
PHP 7
PHP 7PHP 7
PHP 7
 
PHP para Adultos: Clean Code e Object Calisthenics
PHP para Adultos: Clean Code e Object CalisthenicsPHP para Adultos: Clean Code e Object Calisthenics
PHP para Adultos: Clean Code e Object Calisthenics
 
ORM dont kill your DB, developers do
ORM dont kill your DB, developers doORM dont kill your DB, developers do
ORM dont kill your DB, developers do
 
PHPubSP Object Calisthenics aplicado ao PHP
PHPubSP Object Calisthenics aplicado ao PHPPHPubSP Object Calisthenics aplicado ao PHP
PHPubSP Object Calisthenics aplicado ao PHP
 
Javascript para adultos
Javascript para adultosJavascript para adultos
Javascript para adultos
 
Dependency injection
Dependency injectionDependency injection
Dependency injection
 
Doctrine2 Seminário PHP
Doctrine2 Seminário PHPDoctrine2 Seminário PHP
Doctrine2 Seminário PHP
 
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHPIPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
 
Doctrine 2.0: A evolução da persistência em PHP
Doctrine 2.0: A evolução da persistência em PHPDoctrine 2.0: A evolução da persistência em PHP
Doctrine 2.0: A evolução da persistência em PHP
 
PHP, Daemons e Multimedia
PHP, Daemons e MultimediaPHP, Daemons e Multimedia
PHP, Daemons e Multimedia
 
Doctrine 2.0 Enterprise Persistence Layer for PHP
Doctrine 2.0 Enterprise Persistence Layer for PHPDoctrine 2.0 Enterprise Persistence Layer for PHP
Doctrine 2.0 Enterprise Persistence Layer for PHP
 
Desenvolvimento Agil Com Doctrine Orm
Desenvolvimento Agil Com Doctrine OrmDesenvolvimento Agil Com Doctrine Orm
Desenvolvimento Agil Com Doctrine Orm
 

Recently uploaded

Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 

Recently uploaded (20)

Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 

Object Calisthenics Applied to PHP

  • 1. Object Calisthenics Applied to PHP
  • 2. Object Calisthenics The speaker @guilhermeblanco http://github.com/guilhermeblanco
  • 4. Object Calisthenics Erm... WTH is Object Calisthenics? ‣ Object Calisthenics
  • 5. Object Calisthenics Erm... WTH is Object Calisthenics? ‣ Object Calisthenics Term derived from greek, “exercise”, under the context of gymnastics.
  • 6. Object Calisthenics Erm... 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. Object Calisthenics Motivation ‣ Readable Code ‣ Comprehensible ‣ Testable ‣ Maintainable Learning about good code practices at Object CaIisthenics talk of @guilhermeblanco on @gtaphp
  • 8. Object Calisthenics Rules ‣ Nine (9) rules “very” simple...
  • 9. Object Calisthenics Rule 1: Only one indentation level per method ‣ Only one indentation level per method
  • 10. Object Calisthenics Rule 1: Only one indentation level per method public 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. Object Calisthenics Rule 1: Only one indentation level per method public 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. Object Calisthenics Rule 1: Only one indentation level per method public 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. Object Calisthenics Rule 1: Only one indentation level per method public 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. Object Calisthenics Rule 1: Only one indentation level per method public 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. Object Calisthenics Rule 1: Only one indentation level per method public 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. Object Calisthenics Rule 1: Only one indentation level per method public 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. Object Calisthenics Rule 1: Only one indentation level per method 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) ? "The field {$field} cannot be empty!" : "{$message}"; throw new Tss_FormException( $errorMessage, 3, 'javascript:history.back();' ); } }
  • 18. Object Calisthenics Rule 1: Only one indentation level per method 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) ? "The field {$field} cannot be empty!" : "{$message}"; throw new Tss_FormException( $errorMessage, 3, 'javascript:history.back();' ); } }
  • 19. Object Calisthenics Rule 2: Do not use the “else” keyword ‣ Never use the “else” keyword
  • 20. Object Calisthenics Rule 2: Do not use the “else” keyword function 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. Object Calisthenics Rule 2: Do not use the “else” keyword function 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. Object Calisthenics Rule 2: Do not use the “else” keyword function 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. Object Calisthenics Rule 2: Do not use the “else” keyword function 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. Object Calisthenics Rule 3: Wrap primitive types and strings ‣ Wrap all primitive types and strings
  • 25. Object Calisthenics Rule 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. Object Calisthenics Rule 3: Wrap primitive types and strings ‣ But... if the variable of primitive type has a behavior, it must be encapsulated
  • 27. Object Calisthenics Rule 3: Wrap primitive types and strings class UIComponent { ! // ... ! public function repaint($animate = true) { // ... } } // ... $component->repaint(false);
  • 28. Object Calisthenics Rule 3: Wrap primitive types and strings class UIComponent { ! // ... ! public function repaint($animate = true) { // ... } } // ... $component->repaint(false);
  • 29. Object Calisthenics Rule 3: Wrap primitive types and strings class UIComponent { ! // ... ! public function repaint(Animate $animate) { // ... } } class Animate { public $animate; public function __construct($animate = true) { $this->animate = $animate; } } // ... $component->repaint(new Animate(false));
  • 30. Object Calisthenics Rule 4: Only one dot per line ‣ Only one dot (arrow for PHP) per line
  • 31. Object Calisthenics Rule 4: Only one dot per line ‣ Not applicable to PHP...
  • 32. Object Calisthenics Rule 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. Object Calisthenics Rule 4: Only one dot per line ‣ We could adapt to the language, contemplating...
  • 34. Object Calisthenics Rule 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. Object Calisthenics Rule 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. Object Calisthenics Rule 5: Do not abbreviate ‣ Do not abbreviate
  • 37. Object Calisthenics Rule 5: Do not abbreviate
  • 38. Object Calisthenics Rule 5: Do not abbreviate ‣ Think about it... why do you want to abbreviate?
  • 39. Object Calisthenics Rule 5: Do not abbreviate ‣ Think about it... why do you want to abbreviate? ‣ Write the same name repeatedly?
  • 40. Object Calisthenics Rule 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. Object Calisthenics Rule 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. Object Calisthenics Rule 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. Object Calisthenics Rule 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. Object Calisthenics Rule 6: Keep your entities small ‣ Keep your entities small
  • 45. Object Calisthenics Rule 6: Keep your entities small ‣ Original rule: 50 lines per class
  • 46. Object Calisthenics Rule 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. Object Calisthenics Rule 7: Do not create classes with more than 2 instance variables ‣ Do not create classes with more than 2 instance variables
  • 48. Object Calisthenics Rule 7: Do not create classes with more than 2 instance variables ‣ Objective: ‣ Low cohesion ‣ Better encapsulation
  • 49. Object Calisthenics Rule 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. Object Calisthenics Rule 8: Use first class collections ‣ Use first class collections
  • 51. Object Calisthenics Rule 8: Use first class collections ‣ The rule is simple: Any class that contains a collection (array to PHP), cannot contain any other properties
  • 52. Object Calisthenics Rule 8: Use first class collections ‣ Objectives: ‣ Specific behaviors have a good place to stay ‣ Filtering, combining, mapping, ...
  • 53. Object Calisthenics Rule 8: Use first class collections ‣ DoctrineCommonCollectionsArrayCollection ‣ Countable ‣ IteratorAggregate (inherits Traversable) ‣ ArrayAccess
  • 54. Object Calisthenics Rule 9: Do not create getter/setter methods to properties ‣ Do not create getter/setter methods to properties
  • 55. Object Calisthenics Rule 9: Do not create getter/setter methods to properties ‣ Non-applicable to PHP due to language’s nature
  • 56. Object Calisthenics Rule 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. Object Calisthenics “Rule 10”: Document your code! ‣ Document your code!!!!!!!!!!!!!!!!!
  • 58. Object Calisthenics That’s all folks! ‣ Questions? @guilhermeblanco http://github.com/guilhermeblanco

Editor's Notes

  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