Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

PHP object calisthenics

259 views

Published on

9 programming exercises to change the way you write code

Published in: Engineering
  • Be the first to comment

PHP object calisthenics

  1. 1. PHP - Object Calisthenics
  2. 2. I am Giorgio Cefaro I work as Lead Software Engineer in Hootsuite You can find me at @giorrrgio Hello!
  3. 3. “ Our code sucks! let’s fix it!
  4. 4. Calisthenics /ˌkalɪsˈθɛnɪks/ kalòs (καλός) good sthénos (σθένος) strength
  5. 5. Calisthenics are not rules
  6. 6. Code class SpreadSheet { private $headers; private $rows; public function printCSV(string $endLine, string $separator): string { $sheet = $this->headers . $endLine; foreach ($this->rows as $row) { foreach ($row as $cell) { $sheet .= $cell->print() . $separator; } $sheet .= $endLine; } return $sheet; } }
  7. 7. Only one level of indentation per line 1
  8. 8. Code class SpreadSheet { private $headers; private $rows; public function printCSV(string $endLine, string $separator): string { return $this->headers . $endLine . $this->printRows(); } private function printRows(string $endLine, string $separator): string { $printed = ''; foreach ($this->rows as $row) { $printed .= $this->printRow($row, $separator) . $endLine; } return $printed; } private function printRow(array $row, string $separator): string { $printed = ''; foreach ($row as $cell) { $printed .= $cell->print() . $separator; } return $printed; } }
  9. 9. Code class SpreadSheet { public function isMultitab(): bool { if (count($this->tabs) > 1) { return true; } else { return false; } } }
  10. 10. Don’t use the ELSE keyword 2
  11. 11. Code class SpreadSheet { public function isMultitab(): bool { if (count($this->tabs) > 1) { return true; } return false; } }
  12. 12. Code class Task { /** @var int Task priority. */ private $priority; public function isHighPriority(): bool { return $this->priority > 9; } }
  13. 13. Wrap all primitives and strings 3
  14. 14. Code class Task { /** @var Priority Task priority. */ private $priority; public function isHighPriority(): bool { return $this->priority->isHigh(); } } class Priority { const PRIORITY_HIGH = 9; /** @var int priority value. */ private $value; public function isHigh(): bool { return $this->value > self::PRIORITY_HIGH; } }
  15. 15. Code class SpreadSheet { private $headers; private $title; private $rows; public function __construct( string $headers, string $title, array $rows) { //[...] } public function addRow(Row $row) { $this->rows[] = $row; } }
  16. 16. First class collections 4
  17. 17. Code class SpreadSheet { private $headers; private $title; private $rows; public function __construct(string $headers, string $title, RowCollection $rows) { //[...] } public function addRow(Row $row) { $this->rows->add($row); } } class RowCollection implements ArrayAccess { private $rows; public function __construct(array $rows) { $this->rows = $rows; } //[...] }
  18. 18. Code class SpreadSheet { private $user; public function userCanUseSpreadsheet() { return $this->user->getSettings()->canUseSpreadsheet(); } }
  19. 19. One arrow per line5
  20. 20. ● Each unit should have only limited knowledge about other units: only units "closely" related to the current unit. ● Each unit should only talk to its friends; don't talk to strangers. ● Only talk to your immediate friends. Law of Demeter
  21. 21. Code class SpreadSheet { private $user; public function userCanUseSpreadsheet() { return $this->user->canUseSpreadsheet(); } } class User { private $settings; public function canUseSpreadsheet() { return $this->settings->canUseSpreadsheet(); } }
  22. 22. Don’t abbreviate6
  23. 23. Keep all entities small 7
  24. 24. No classes with more than two instance variables 8
  25. 25. “ Decomposing objects from a set of attributes into a hierarchy of collaborating objects, leads much more directly to an effective object model https://github.com/TheLadders/object-calisthenics#rule-8-no-classes-with-more-than-two-instance-variables
  26. 26. Code class User { private $firstname; private $lastname; public function getFirstname() { return $this->firstname; } public function setFirstname($firstname) { return $this->firstname = $firstname; } public function getLastname() { return $this->lastname; } public function setLastname($lastname) { return $this->lastname = $lastname; } }
  27. 27. No Getters No Setters No Properties 9
  28. 28. Code class User { private $firstname; private $lastname; private function __constructor(string $firstname, string $lastname) { $this->firstname = $firstname; $this->lastname = $lastname; } public static function create(string $firstname, string $lastname): self { return new self($firstname, $lastname); } public function toArray(): array { return [ 'firstname' => $firstname, 'lastname' => $lastname ]; } }
  29. 29. Any questions ? You can find me at ◉ @giorrrgio Thanks!

×