SlideShare una empresa de Scribd logo
1 de 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

Más contenido relacionado

La actualidad más candente

프론트엔드 코딩 컨벤션 자동화 도구
프론트엔드 코딩 컨벤션 자동화 도구프론트엔드 코딩 컨벤션 자동화 도구
프론트엔드 코딩 컨벤션 자동화 도구Taegon Kim
 
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
 
Spring Data JPA from 0-100 in 60 minutes
Spring Data JPA from 0-100 in 60 minutesSpring Data JPA from 0-100 in 60 minutes
Spring Data JPA from 0-100 in 60 minutesVMware Tanzu
 
Web api crud operations
Web api crud operationsWeb api crud operations
Web api crud operationsEyal Vardi
 
Serializing EMF models with Xtext
Serializing EMF models with XtextSerializing EMF models with Xtext
Serializing EMF models with Xtextmeysholdt
 
Nest.js Introduction
Nest.js IntroductionNest.js Introduction
Nest.js IntroductionTakuya Tejima
 
JDBC - JPA - Spring Data
JDBC - JPA - Spring DataJDBC - JPA - Spring Data
JDBC - JPA - Spring DataArturs Drozdovs
 
기가박스 영화관 운영 시스템 구축마지막
기가박스 영화관 운영 시스템 구축마지막기가박스 영화관 운영 시스템 구축마지막
기가박스 영화관 운영 시스템 구축마지막ssuser5280ce
 
PHP 語法基礎與物件導向
PHP 語法基礎與物件導向PHP 語法基礎與物件導向
PHP 語法基礎與物件導向Shengyou Fan
 
Javascript this keyword
Javascript this keywordJavascript this keyword
Javascript this keywordPham Huy Tung
 
Clean code and Code Smells
Clean code and Code SmellsClean code and Code Smells
Clean code and Code SmellsMario Sangiorgio
 
Advanced Javascript
Advanced JavascriptAdvanced Javascript
Advanced JavascriptAdieu
 

La actualidad más candente (20)

프론트엔드 코딩 컨벤션 자동화 도구
프론트엔드 코딩 컨벤션 자동화 도구프론트엔드 코딩 컨벤션 자동화 도구
프론트엔드 코딩 컨벤션 자동화 도구
 
Clean code slide
Clean code slideClean code slide
Clean code slide
 
JavaScript Inheritance
JavaScript InheritanceJavaScript Inheritance
JavaScript Inheritance
 
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
 
Spring Data JPA from 0-100 in 60 minutes
Spring Data JPA from 0-100 in 60 minutesSpring Data JPA from 0-100 in 60 minutes
Spring Data JPA from 0-100 in 60 minutes
 
Web api crud operations
Web api crud operationsWeb api crud operations
Web api crud operations
 
Serializing EMF models with Xtext
Serializing EMF models with XtextSerializing EMF models with Xtext
Serializing EMF models with Xtext
 
SQL Injection
SQL Injection SQL Injection
SQL Injection
 
JUnit 5
JUnit 5JUnit 5
JUnit 5
 
Sql injection
Sql injectionSql injection
Sql injection
 
Nest.js Introduction
Nest.js IntroductionNest.js Introduction
Nest.js Introduction
 
JDBC - JPA - Spring Data
JDBC - JPA - Spring DataJDBC - JPA - Spring Data
JDBC - JPA - Spring Data
 
기가박스 영화관 운영 시스템 구축마지막
기가박스 영화관 운영 시스템 구축마지막기가박스 영화관 운영 시스템 구축마지막
기가박스 영화관 운영 시스템 구축마지막
 
PHP 語法基礎與物件導向
PHP 語法基礎與物件導向PHP 語法基礎與物件導向
PHP 語法基礎與物件導向
 
Java script
Java scriptJava script
Java script
 
Javascript this keyword
Javascript this keywordJavascript this keyword
Javascript this keyword
 
Clean code and Code Smells
Clean code and Code SmellsClean code and Code Smells
Clean code and Code Smells
 
Advanced Javascript
Advanced JavascriptAdvanced Javascript
Advanced Javascript
 
Sql injection
Sql injectionSql injection
Sql injection
 
Broadleaf Presents Thymeleaf
Broadleaf Presents ThymeleafBroadleaf Presents Thymeleaf
Broadleaf Presents Thymeleaf
 

Similar a 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
 
You code sucks, let's fix it
You code sucks, let's fix itYou code sucks, let's fix it
You code sucks, let's fix itRafael 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
 

Similar a 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
 
You code sucks, let's fix it
You code sucks, let's fix itYou code sucks, let's fix it
You code sucks, let's fix it
 
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
 

Más de 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
 

Más de 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
 

Último

Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
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
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
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
 
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
 
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
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesZilliz
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
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
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfSeasiaInfotech2
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 

Último (20)

Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
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
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
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
 
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
 
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
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector Databases
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
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
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdf
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 

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

Notas del editor

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