Pro Yearly is on sale from $80 to $50! »

Writing code that speaks

Writing code that speaks

Code is read many more times than it is written. In this talk I'm going to walk through simple, practical examples of how you can give your code a voice. We're going to explore the power of word choice, and how you can develop naming habits that lead to beneficial refactorings.

D20a680b224928e9743c966ebb06d3ce?s=128

Caleb Porzio

June 16, 2017
Tweet

Transcript

  1. None
  2. Caleb Porzio @calebporzio

  3. None
  4. Writing code that speaks

  5. None
  6. None
  7. "Any fool can write code that a computer can understand.

    Good programmers write code that humans can understand." Martin Fowler
  8. "Indeed, the ratio of time spent reading versus writing is

    well over 10 to 1. We are constantly reading old code as part of the effort to write new code. ... [Therefore,] making it easy to read makes it easier to write." Uncle Bob (Robert C Martin)
  9. Give your code a voice

  10. 1. Avoid meaningless words 2. Strive for consistency 3. Don't

    make my brain hurt 4. Name according to scope 5. Don't make me look things up 6. Leverage metaphors
  11. 1. Avoid meaningless words Words that put my brain to

    sleep !
  12. $data (1. Avoid meaningless words)

  13. $data $data = ['id' => 1]; $client->get('/user', $data); (1. Avoid

    meaningless words)
  14. $data $payload = ['id' => 1]; $client->get('/user', $payload); (1. Avoid

    meaningless words)
  15. $items $items = getNavLinks(); foreach ($items as $item) {... (1.

    Avoid meaningless words)
  16. $items $links = getNavLinks(); foreach ($links as $link) {... (1.

    Avoid meaningless words)
  17. ! The more abstracted your code is, the more abstract

    your words will be (1. Avoid meaningless words)
  18. Drop the type suffix $namesArray = ['jack', 'jill']; (1. Avoid

    meaningless words)
  19. Drop the type suffix $names = ['jack', 'jill']; (1. Avoid

    meaningless words)
  20. Drop the type suffix $createdAtTimestamp = new DateTime; (1. Avoid

    meaningless words)
  21. Drop the type suffix $createdAt = new DateTime; (1. Avoid

    meaningless words)
  22. Hungarian notation ! $aNames = ['bob', 'carol', 'jim']; $sName =

    'jack'; $iAge = 23; (1. Avoid meaningless words)
  23. Hungarian notation ! $names = ['bob', 'carol', 'jim']; $name =

    'jack'; $age = 23; (1. Avoid meaningless words)
  24. Service classes $mailService = new MailService; $mailService->send($msg); (1. Avoid meaningless

    words)
  25. Service classes $mailer = new Mailer; $mailer->send($message); (1. Avoid meaningless

    words)
  26. $thing1, $thing2 (1. Avoid meaningless words)

  27. $thing1, $thing2 $user1 = factory(User::class); $user2 = factory(User::class); login($user1); $this->assertTrue($user1->loggedIn());

    $this->assertFalse($user2->loggedIn()); (1. Avoid meaningless words)
  28. $thing1, $thing2 $user = factory(User::class); $visitor = factory(User::class); login($user); $this->assertTrue($user->loggedIn());

    $this->assertFalse($visitor->loggedIn()); (1. Avoid meaningless words)
  29. 1. Avoid meaningless words 2. Strive for consistency

  30. Pick a word and stick with it echo $blog->body; echo

    $comment->text; echo $testimonial->content; (2. Strive for consistency)
  31. Pick a word and stick with it echo $blog->body; echo

    $comment->body; echo $testimonial->body; (2. Strive for consistency)
  32. Pick a word and stick with it $post->image; $user->photo; $tag->thumbnail;

    (2. Strive for consistency)
  33. Pick a word and stick with it $post->image; $user->image; $tag->image;

    (2. Strive for consistency)
  34. Pick a word and stick with it service.api_key service.key service.public_key

    service.secret_key service.api_secret service.api_public service.secret ... (2. Strive for consistency)
  35. Pick a word and stick with it service.api_key service.api_secret (2.

    Strive for consistency)
  36. 1. Avoid meaningless words 2. Strive for consistency 3. Don't

    make my brain hurt
  37. Abbreviations I'm ok with ! auth authentication // TODO admin

    administrator id identifier db database i iteration int, bool integer / boolean e, z exception / zonda (3. Don't make my brain hurt)
  38. Abbreviations I'm NOT ok with ! addr address attr attribute

    err error arr array opt option msg message img image (3. Don't make my brain hurt)
  39. Dates date('j') / date('t') * 100; (3. Don't make my

    brain hurt)
  40. Dates $dayOfMonth = date('j'); $totalDaysInMonth = date('t'); $dayOfMonth / $totalDaysInMonth

    * 100; (3. Don't make my brain hurt)
  41. Dates (new DateTime)->setDate(date('Y'), date('m'), 1)->setTime(12, 0, 0); (3. Don't make

    my brain hurt)
  42. Dates new DateTime('first day of this month midnight'); (3. Don't

    make my brain hurt)
  43. Ugh! Regex preg_replace('/\s\s+/', ' ', $title); (3. Don't make my

    brain hurt)
  44. Ugh! Regex stripOutExtraWhitespace($title); (3. Don't make my brain hurt)

  45. Negatives ! if (! $post->isExpired()) { (3. Don't make my

    brain hurt)
  46. Negatives ! if ($post->isActive()) { (3. Don't make my brain

    hurt)
  47. Double Negatives ! ! $users->filter(function ($user) { return $user->group !==

    'admin'; }); (3. Don't make my brain hurt)
  48. Double Negatives ! ! $users->reject(function ($user) { return $user->group ===

    'admin'; }); (3. Don't make my brain hurt)
  49. None
  50. 1. Avoid meaningless words 2. Strive for consistency 3. Don't

    make my brain hurt 4. Name according to scope
  51. Compound method names class Cart { public function addProduct() {};

    public function removeProduct() {}; public function changeProduct() {}; } $cart->addProduct(); (4. Name according to scope)
  52. Compound method names class Cart { public products; } class

    Products { public function add() {}; public function remove() {}; public function change() {}; } $cart->products->add($product); (4. Name according to scope)
  53. ! Your names may be telling you that your code

    is ready for a refactoring
  54. Compound variable names $transactionId; $transactionDate; $transactionAmount; (4. Name according to

    scope)
  55. Compound variable names $transaction->id; $transaction->date; $transaction->amount; (4. Name according to

    scope)
  56. 1. Avoid meaningless words 2. Strive for consistency 3. Don't

    make my brain hurt 4. Name according to scope 5. Don't make me look things up
  57. Bare parameters new Color(0, 12, 66); (5. Don't make me

    look things up)
  58. Bare parameters Color::fromRGB(255, 255, 255); Color::fromHSL(0, 0, 100); (5. Don't

    make me look things up)
  59. Bare parameters new HttpRequest(500); (5. Don't make me look things

    up)
  60. Bare parameters new HttpRequest($timeoutInSeconds = 500); (5. Don't make me

    look things up)
  61. Boolean flags json_decode($json, true); (5. Don't make me look things

    up)
  62. Boolean flags json_decode($json, $returnArray = true); (5. Don't make me

    look things up)
  63. Array Indexes $user = DB::fetchRowArray(... echo $user[2]; (5. Don't make

    me look things up)
  64. Array Indexes $user = DB::fetchRowAssociativeArray(... echo $user['email']; (5. Don't make

    me look things up)
  65. Bare integer $response = $request->post('/users', $payload); $this->assertEquals(201, $response->statusCode()); (5. Don't

    make me look things up)
  66. Bare integer class HttpStatus { const CREATED = 201; }

    $response = $request->post('/users', $payload); $this->assertEquals(HttpStatus::CREATED, $response->statusCode()); (5. Don't make me look things up)
  67. Implicit method name $post->publish(); // queues internally (5. Don't make

    me look things up)
  68. Implicit method name $post->queueAndPublish(); (5. Don't make me look things

    up)
  69. Implicit method name Post::getFirst(); // creates a new post if

    can't find one (5. Don't make me look things up)
  70. Implicit method name Post::getFirstOrCreate(); (5. Don't make me look things

    up)
  71. 1. Avoid meaningless words 2. Strive for consistency 3. Don't

    make my brain hurt 4. Name according to scope 5. Don't make me look things up 6. Leverage metaphors
  72. None
  73. "This transfer of some quality of the known to the

    unknown is like a beam of light; we "see" (that is, we understand) something about the unknown in the light of the known." Mary Oliver (A Poetry Handbook)
  74. Common pattern in apps $admin->logInAsOtherUser($user); (6. Leverage metaphors)

  75. Common pattern in apps $admin->impersonate($user); (6. Leverage metaphors)

  76. Common pattern in APIs $client->get('/users/currently_logged_in_user'); (6. Leverage metaphors)

  77. Common pattern in APIs $client->get('/users/me'); (6. Leverage metaphors)

  78. Wrapping it up

  79. 1. Avoid meaningless words 2. Strive for consistency 3. Don't

    make my brain hurt 4. Name according to scope 5. Don't make me look things up 6. Leverage metaphors
  80. Choosing words is fun and creative

  81. Our job is to listen and understand

  82. Write code that speaks

  83. None