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

날로 먹는 Django admin 활용
날로 먹는 Django admin 활용날로 먹는 Django admin 활용
날로 먹는 Django admin 활용KyeongMook "Kay" Cha
 
Exception handling
Exception handlingException handling
Exception handlingAnna Pietras
 
Beyond Java: 자바 8을 중심으로 본 자바의 혁신
Beyond Java: 자바 8을 중심으로 본 자바의 혁신Beyond Java: 자바 8을 중심으로 본 자바의 혁신
Beyond Java: 자바 8을 중심으로 본 자바의 혁신Sungchul Park
 
Introduction to jQuery
Introduction to jQueryIntroduction to jQuery
Introduction to jQuerymanugoel2003
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Domenic Denicola
 
I got 99 problems, but ReST ain't one
I got 99 problems, but ReST ain't oneI got 99 problems, but ReST ain't one
I got 99 problems, but ReST ain't oneAdrian Cole
 
How object oriented are you feeling today?
How object oriented are you feeling today?How object oriented are you feeling today?
How object oriented are you feeling today?Krzysztof Jelski
 
Domain Driven Design with the F# type System -- NDC London 2013
Domain Driven Design with the F# type System -- NDC London 2013Domain Driven Design with the F# type System -- NDC London 2013
Domain Driven Design with the F# type System -- NDC London 2013Scott Wlaschin
 
간단한 블로그를 만들며 Django 이해하기
간단한 블로그를 만들며 Django 이해하기간단한 블로그를 만들며 Django 이해하기
간단한 블로그를 만들며 Django 이해하기Kyoung Up Jung
 
Node.js Express
Node.js  ExpressNode.js  Express
Node.js ExpressEyal Vardi
 
Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2José Paumard
 
Django로 쇼핑몰 만들자
Django로 쇼핑몰 만들자Django로 쇼핑몰 만들자
Django로 쇼핑몰 만들자Kyoung Up Jung
 
Alasql fast JavaScript in-memory SQL database
Alasql fast JavaScript in-memory SQL databaseAlasql fast JavaScript in-memory SQL database
Alasql fast JavaScript in-memory SQL databaseAndrey Gershun
 
Django, 저는 이렇게 씁니다.
Django, 저는 이렇게 씁니다.Django, 저는 이렇게 씁니다.
Django, 저는 이렇게 씁니다.Kyoung Up Jung
 

What's hot (20)

날로 먹는 Django admin 활용
날로 먹는 Django admin 활용날로 먹는 Django admin 활용
날로 먹는 Django admin 활용
 
Exception handling
Exception handlingException handling
Exception handling
 
Beyond Java: 자바 8을 중심으로 본 자바의 혁신
Beyond Java: 자바 8을 중심으로 본 자바의 혁신Beyond Java: 자바 8을 중심으로 본 자바의 혁신
Beyond Java: 자바 8을 중심으로 본 자바의 혁신
 
Django Girls Tutorial
Django Girls TutorialDjango Girls Tutorial
Django Girls Tutorial
 
Introduction to jQuery
Introduction to jQueryIntroduction to jQuery
Introduction to jQuery
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
 
I got 99 problems, but ReST ain't one
I got 99 problems, but ReST ain't oneI got 99 problems, but ReST ain't one
I got 99 problems, but ReST ain't one
 
Sql injection
Sql injectionSql injection
Sql injection
 
How object oriented are you feeling today?
How object oriented are you feeling today?How object oriented are you feeling today?
How object oriented are you feeling today?
 
Domain Driven Design with the F# type System -- NDC London 2013
Domain Driven Design with the F# type System -- NDC London 2013Domain Driven Design with the F# type System -- NDC London 2013
Domain Driven Design with the F# type System -- NDC London 2013
 
간단한 블로그를 만들며 Django 이해하기
간단한 블로그를 만들며 Django 이해하기간단한 블로그를 만들며 Django 이해하기
간단한 블로그를 만들며 Django 이해하기
 
Node.js Express
Node.js  ExpressNode.js  Express
Node.js Express
 
Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2
 
Lesson 5 php operators
Lesson 5   php operatorsLesson 5   php operators
Lesson 5 php operators
 
Sequelize
SequelizeSequelize
Sequelize
 
Django로 쇼핑몰 만들자
Django로 쇼핑몰 만들자Django로 쇼핑몰 만들자
Django로 쇼핑몰 만들자
 
jQuery
jQueryjQuery
jQuery
 
Alasql fast JavaScript in-memory SQL database
Alasql fast JavaScript in-memory SQL databaseAlasql fast JavaScript in-memory SQL database
Alasql fast JavaScript in-memory SQL database
 
Php Tutorials for Beginners
Php Tutorials for BeginnersPhp Tutorials for Beginners
Php Tutorials for Beginners
 
Django, 저는 이렇게 씁니다.
Django, 저는 이렇게 씁니다.Django, 저는 이렇게 씁니다.
Django, 저는 이렇게 씁니다.
 

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

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 (12)

Enterprise php
Enterprise phpEnterprise php
Enterprise php
 
PHP 7
PHP 7PHP 7
PHP 7
 
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

Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...AliaaTarek5
 
Visualising and forecasting stocks using Dash
Visualising and forecasting stocks using DashVisualising and forecasting stocks using Dash
Visualising and forecasting stocks using Dashnarutouzumaki53779
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
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
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
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
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 

Recently uploaded (20)

Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
 
Visualising and forecasting stocks using Dash
Visualising and forecasting stocks using DashVisualising and forecasting stocks using Dash
Visualising and forecasting stocks using Dash
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
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
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
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
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 

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