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.
Writing code
that lasts.
Rafael Dohms

@rdohms
photo: djandyw.com
Writing code 

you won’t hate tomorrow.
Rafael Dohms

@rdohms
photo: djandyw.com
Lead Backend Engineer
Rafael Dohms
jobs.usabilla.com
@rdohms on twitter
Lead Backend Engineer
Rafael Dohms
jobs.usabilla.com
FeedbackFeedback
@rdohms on twitter
photo: Rob Allen (@akrabat)
REWRITE
ALL THE CODE!
image: hyperboleandahalf
Real Developers,
SHIP STUFF.
photo: Glyn Lowe Photoworks
How do we find
balance?
photo: Kalexanderson
Code has an
expiration date
photo: CarbonNYC
Code is
perishable, it rots.
photo by: massdistraction
Code Evolves
photo by: kevin dooley
Languages evolve.
photo by: raneko
You evolve.
photo by: Kaptain Kobold
Complexity 

kills
Comprehension
photo: osbornb
Bad Design
photo: miskan
Bad specs
NIH
source: Urban dictionary
photo by: John 'K'
NIH
| nɒt ɪnˈventɪd hɪə |

Not Invented Here —The German art of humiliating any technology,
agricultural product, or (medi...
The Solution™
photo: Ian Sane
Improve code
Improve code
make it easier to comprehend
Improve code
make it easier to comprehend
make it flexible
Improve code
make it easier to comprehend
make it flexible
make it tested
Improve code
make it easier to comprehend
make it flexible
make it tested
make it easier to replace, refactor
Improve code
make it easier to comprehend
make it flexible
make it tested
make it easier to replace, refactor
make it not e...
Testing
photo by: jeffkrause
"Refactoring without tests
is just changing stuff."
Good Design
Concepts
Single Responsibility

Open and Close

Liskov substitution

Interface Segregation

Dependency Inversion
Singleton

Tight C...
Design Patterns
photo by halloweenstock
Domain Driven Design
with Ubiquitous Language
photo by lwr
Modular Architecture
CQRS, Event Sourcing, Micro Services
photo by medialoog
Package
Managers
PIE
Proudly

Invented

Elsewhere
photo by: boston_public_library
Object Calisthenics
Jeff Bay
Calisthenics
/ˌkaləsˈTHeniks/
Calisthenics are a form of dynamic exercise consisting of a variety of
simple, often rhythmi...
These are
exercises, not rules. photo by: david_a_l
#1
Only one
indentation level
per method.
photo by: justinliew
#2
Do not 

use else
photo by: justinliew
public function createPost($request)
{
$entity = new Post();
$form = new MyForm($entity);
$form->bind($request);
if ($form...
public function createPost($request)
{
$entity = new Post();
$form = new MyForm($entity);
$form->bind($request);
if ($form...
public function createPost($request)
{
$entity = new Post();
$form = new MyForm($entity);
$form->bind($request);
if ($form...
public function createPost($request)
{
$entity = new Post();
$form = new MyForm($entity);
$form->bind($request);
if ($form...
public function createPost($request)
{
$entity = new Post();
$repository = $this->getRepository('MyBundle:Post');
$form = ...
public function createPost($request)
{
$entity = new Post();
$repository = $this->getRepository('MyBundle:Post');
$form = ...
public function createPost($request)
{
$entity = new Post();
$repository = $this->getRepository('MyBundle:Post');
$form = ...
public function createPost($request)
{
$entity = new Post();
$repository = $this->getRepository('MyBundle:Post');
$form = ...
public function createPost($request)
{
$repository = $this->getRepository('MyBundle:Post');
$entity = new Post();
$reposit...
public function createPost($request)
{
$repository = $this->getRepository('MyBundle:Post');
$entity = new Post();
$reposit...
public function createPost($request)
{
$repository = $this->getRepository('MyBundle:Post');
$entity = new Post();
$reposit...
#3
Wrap primitive
types, if they
contain behavior
photo by: justinliew
$component->repaint(false);
$component->repaint( new Animate(false) );
use MoneyMoney;
$fiveEur = Money::EUR(500);
$tenEur = $fiveEur->add($fiveEur);
#4
Only one 

-> per line
photo by: justinliew
$user = $this->get('security.token_storage')->getToken()->getUser();
$user = $this->get('security.token_storage')->getToken()->getUser();
null
#5
Do not
abbreviate.
photo by: justinliew
if($sx >= $sy) {
if ($sx > $strSysMatImgW) {
$ny = $strSysMatImgW * $sy / $sx;
$nx = $strSysMatImgW;
}
if ($ny > $strSysMa...
#6
Keep your
classes small.
photo by: justinliew
#7
Limit your
instance
variables to 2
photo by: justinliew
class MyRegistrationService
{
protected $userService;
protected $passwordService;
protected $logger;
protected $translator...
#8
Use first class
collections
photo by: justinliew
#9
Don’t use getters
and setters.
photo by: justinliew
public function getScore($request)
{
return $this->score;
}
public function setScore($score)
{
$this->score = $score;
}
$g...
public function collectedCoin()
{
$this->score += 1;
}
$game->collectedCoin();
#10
Document
your code.
photo by: justinliew
Your turn.
Improve
yourself!
Read lots of
code!
Write simpler
code.
Try Object Calisthenics
for a month.
Use someone 

else’s code,

and share yours!
Thank you.
http://slides.doh.ms
http://doh.ms
@rdohms
jobs.usabilla.com
looking for a job in Amsterdam?
http://l.doh.ms/object-calisthenics-links
Books
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
Upcoming SlideShare
Loading in …5
×

“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf

3,454 views

Published on

As developers we write code everyday, only to frown at it a week after that. Why do we have such a hard time with code written by others and ourselves, this raging desire to rewrite everything we see? Writing code that survives the test of time and self judgment is a matter of clarity and simplicity. Let's talk about growing, learning and improving our code with calisthenics, readability and good design.

Published in: Technology

“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf

  1. 1. Writing code that lasts. Rafael Dohms
 @rdohms photo: djandyw.com
  2. 2. Writing code 
 you won’t hate tomorrow. Rafael Dohms
 @rdohms photo: djandyw.com
  3. 3. Lead Backend Engineer Rafael Dohms jobs.usabilla.com @rdohms on twitter
  4. 4. Lead Backend Engineer Rafael Dohms jobs.usabilla.com FeedbackFeedback @rdohms on twitter
  5. 5. photo: Rob Allen (@akrabat)
  6. 6. REWRITE ALL THE CODE! image: hyperboleandahalf
  7. 7. Real Developers, SHIP STUFF. photo: Glyn Lowe Photoworks
  8. 8. How do we find balance? photo: Kalexanderson
  9. 9. Code has an expiration date photo: CarbonNYC
  10. 10. Code is perishable, it rots. photo by: massdistraction
  11. 11. Code Evolves photo by: kevin dooley
  12. 12. Languages evolve. photo by: raneko
  13. 13. You evolve. photo by: Kaptain Kobold
  14. 14. Complexity 
 kills Comprehension photo: osbornb
  15. 15. Bad Design photo: miskan
  16. 16. Bad specs
  17. 17. NIH source: Urban dictionary photo by: John 'K'
  18. 18. NIH | nɒt ɪnˈventɪd hɪə |
 Not Invented Here —The German art of humiliating any technology, agricultural product, or (medical) scientific work that has not been invented or produced in Germany, Switzerland, or Austria. source: Urban dictionary photo by: John 'K'
  19. 19. The Solution™ photo: Ian Sane
  20. 20. Improve code
  21. 21. Improve code make it easier to comprehend
  22. 22. Improve code make it easier to comprehend make it flexible
  23. 23. Improve code make it easier to comprehend make it flexible make it tested
  24. 24. Improve code make it easier to comprehend make it flexible make it tested make it easier to replace, refactor
  25. 25. Improve code make it easier to comprehend make it flexible make it tested make it easier to replace, refactor make it not exist
  26. 26. Testing photo by: jeffkrause
  27. 27. "Refactoring without tests is just changing stuff."
  28. 28. Good Design Concepts
  29. 29. Single Responsibility
 Open and Close
 Liskov substitution
 Interface Segregation
 Dependency Inversion Singleton
 Tight Coupling
 Untestability
 Premature Optimization
 Indescriptive Naming
 Duplication Solid Stupid ○"
  30. 30. Design Patterns photo by halloweenstock
  31. 31. Domain Driven Design with Ubiquitous Language photo by lwr
  32. 32. Modular Architecture CQRS, Event Sourcing, Micro Services photo by medialoog
  33. 33. Package Managers
  34. 34. PIE Proudly
 Invented
 Elsewhere
  35. 35. photo by: boston_public_library Object Calisthenics Jeff Bay
  36. 36. Calisthenics /ˌkaləsˈTHeniks/ Calisthenics are a form of dynamic exercise consisting of a variety of simple, often rhythmical, movements, generally using minimal equipment or apparatus. photo by: boston_public_library
  37. 37. These are exercises, not rules. photo by: david_a_l
  38. 38. #1 Only one indentation level per method. photo by: justinliew
  39. 39. #2 Do not 
 use else photo by: justinliew
  40. 40. public function createPost($request) { $entity = new Post(); $form = new MyForm($entity); $form->bind($request); if ($form->isValid()){ $repository = $this->getRepository('MyBundle:Post'); if (!$repository->exists($entity) ) { $repository->save($entity); return $this->redirect('create_ok'); } else { $error = "Post Title already exists"; return array('form' => $form, 'error' => $error); } } else { $error = "Invalid fields"; return array('form' => $form, 'error' => $error); } }
  41. 41. public function createPost($request) { $entity = new Post(); $form = new MyForm($entity); $form->bind($request); if ($form->isValid()){ $repository = $this->getRepository('MyBundle:Post'); if (!$repository->exists($entity) ) { $repository->save($entity); return $this->redirect('create_ok'); } else { $error = "Post Title already exists"; return array('form' => $form, 'error' => $error); } } else { $error = "Invalid fields"; return array('form' => $form, 'error' => $error); } } actual goal of function “Create Post"
  42. 42. public function createPost($request) { $entity = new Post(); $form = new MyForm($entity); $form->bind($request); if ($form->isValid()){ $repository = $this->getRepository('MyBundle:Post'); if (!$repository->exists($entity) ) { $repository->save($entity); return $this->redirect('create_ok'); } else { $error = "Post Title already exists"; return array('form' => $form, 'error' => $error); } } else { $error = "Invalid fields"; return array('form' => $form, 'error' => $error); } } this is all error handling
  43. 43. public function createPost($request) { $entity = new Post(); $form = new MyForm($entity); $form->bind($request); if ($form->isValid()){ $repository = $this->getRepository('MyBundle:Post'); if (!$repository->exists($entity) ) { $repository->save($entity); return $this->redirect('create_ok'); } else { $error = "Post Title already exists"; return array('form' => $form, 'error' => $error); } } else { $error = "Invalid fields"; return array('form' => $form, 'error' => $error); } }
  44. 44. public function createPost($request) { $entity = new Post(); $repository = $this->getRepository('MyBundle:Post'); $form = new MyForm($entity); $form->bind($request); if ($form->isValid() === false){ return array('form' => $form, 'error' => 'Invalid fields'); } if ($repository->exists($entity)){ return array('form' => $form, 'error' => 'Duplicate post title'); } $repository->save($entity); return $this->redirect('create_ok'); }
  45. 45. public function createPost($request) { $entity = new Post(); $repository = $this->getRepository('MyBundle:Post'); $form = new MyForm($entity); $form->bind($request); if ($form->isValid() === false){ return array('form' => $form, 'error' => 'Invalid fields'); } if ($repository->exists($entity)){ return array('form' => $form, 'error' => 'Duplicate post title'); } $repository->save($entity); return $this->redirect('create_ok'); } exit condition 1: invalid form
  46. 46. public function createPost($request) { $entity = new Post(); $repository = $this->getRepository('MyBundle:Post'); $form = new MyForm($entity); $form->bind($request); if ($form->isValid() === false){ return array('form' => $form, 'error' => 'Invalid fields'); } if ($repository->exists($entity)){ return array('form' => $form, 'error' => 'Duplicate post title'); } $repository->save($entity); return $this->redirect('create_ok'); } exit condition 2: duplicated post
  47. 47. public function createPost($request) { $entity = new Post(); $repository = $this->getRepository('MyBundle:Post'); $form = new MyForm($entity); $form->bind($request); if ($form->isValid() === false){ return array('form' => $form, 'error' => 'Invalid fields'); } if ($repository->exists($entity)){ return array('form' => $form, 'error' => 'Duplicate post title'); } $repository->save($entity); return $this->redirect('create_ok'); } this is what the method actually does
  48. 48. public function createPost($request) { $repository = $this->getRepository('MyBundle:Post'); $entity = new Post(); $repository->save($entity); return $this->redirect('create_ok'); }
  49. 49. public function createPost($request) { $repository = $this->getRepository('MyBundle:Post'); $entity = new Post(); $repository->save($entity); return $this->redirect('create_ok'); } FormValidationMiddleware UniqueEntityMiddleware
  50. 50. public function createPost($request) { $repository = $this->getRepository('MyBundle:Post'); $entity = new Post(); $repository->save($entity); return $this->redirect('create_ok'); } The power of PSR-7 and middleware FormValidationMiddleware UniqueEntityMiddleware
  51. 51. #3 Wrap primitive types, if they contain behavior photo by: justinliew
  52. 52. $component->repaint(false);
  53. 53. $component->repaint( new Animate(false) );
  54. 54. use MoneyMoney; $fiveEur = Money::EUR(500); $tenEur = $fiveEur->add($fiveEur);
  55. 55. #4 Only one 
 -> per line photo by: justinliew
  56. 56. $user = $this->get('security.token_storage')->getToken()->getUser();
  57. 57. $user = $this->get('security.token_storage')->getToken()->getUser(); null
  58. 58. #5 Do not abbreviate. photo by: justinliew
  59. 59. if($sx >= $sy) { if ($sx > $strSysMatImgW) { $ny = $strSysMatImgW * $sy / $sx; $nx = $strSysMatImgW; } if ($ny > $strSysMatImgH) { $nx = $strSysMatImgH * $sx / $sy; $ny = $strSysMatImgH; } }
  60. 60. #6 Keep your classes small. photo by: justinliew
  61. 61. #7 Limit your instance variables to 2 photo by: justinliew
  62. 62. class MyRegistrationService { protected $userService; protected $passwordService; protected $logger; protected $translator; protected $entityManager; protected $imageCropper; // ... }
  63. 63. #8 Use first class collections photo by: justinliew
  64. 64. #9 Don’t use getters and setters. photo by: justinliew
  65. 65. public function getScore($request) { return $this->score; } public function setScore($score) { $this->score = $score; } $game->setScore($game->getScore() += 1);
  66. 66. public function collectedCoin() { $this->score += 1; } $game->collectedCoin();
  67. 67. #10 Document your code. photo by: justinliew
  68. 68. Your turn.
  69. 69. Improve yourself!
  70. 70. Read lots of code!
  71. 71. Write simpler code.
  72. 72. Try Object Calisthenics for a month.
  73. 73. Use someone 
 else’s code,
 and share yours!
  74. 74. Thank you. http://slides.doh.ms http://doh.ms @rdohms jobs.usabilla.com looking for a job in Amsterdam?
  75. 75. http://l.doh.ms/object-calisthenics-links Books

×