Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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.

Caleb Porzio

June 16, 2017
Tweet

More Decks by Caleb Porzio

Other Decks in Programming

Transcript

  1. View Slide

  2. Caleb Porzio
    @calebporzio

    View Slide

  3. View Slide

  4. Writing code that speaks

    View Slide

  5. View Slide

  6. View Slide

  7. "Any fool can write code that a computer can
    understand. Good programmers write code that
    humans can understand."
    Martin Fowler

    View Slide

  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)

    View Slide

  9. Give your code a voice

    View Slide

  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

    View Slide

  11. 1. Avoid meaningless words
    Words that put my brain to sleep !

    View Slide

  12. $data
    (1. Avoid meaningless words)

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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)

    View Slide

  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)

    View Slide

  29. 1. Avoid meaningless words
    2. Strive for consistency

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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)

    View Slide

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

    View Slide

  36. 1. Avoid meaningless words
    2. Strive for consistency
    3. Don't make my brain hurt

    View Slide

  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)

    View Slide

  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)

    View Slide

  39. Dates
    date('j') / date('t') * 100;
    (3. Don't make my brain hurt)

    View Slide

  40. Dates
    $dayOfMonth = date('j');
    $totalDaysInMonth = date('t');
    $dayOfMonth / $totalDaysInMonth * 100;
    (3. Don't make my brain hurt)

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  49. View Slide

  50. 1. Avoid meaningless words
    2. Strive for consistency
    3. Don't make my brain hurt
    4. Name according to scope

    View Slide

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

    View Slide

  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)

    View Slide

  53. !
    Your names may be telling you that your code is
    ready for a refactoring

    View Slide

  54. Compound variable names
    $transactionId;
    $transactionDate;
    $transactionAmount;
    (4. Name according to scope)

    View Slide

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

    View Slide

  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

    View Slide

  57. Bare parameters
    new Color(0, 12, 66);
    (5. Don't make me look things up)

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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)

    View Slide

  67. Implicit method name
    $post->publish(); // queues internally
    (5. Don't make me look things up)

    View Slide

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

    View Slide

  69. Implicit method name
    Post::getFirst(); // creates a new post if can't find one
    (5. Don't make me look things up)

    View Slide

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

    View Slide

  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

    View Slide

  72. View Slide

  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)

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  78. Wrapping it up

    View Slide

  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

    View Slide

  80. Choosing words is fun and creative

    View Slide

  81. Our job is to listen and understand

    View Slide

  82. Write code that speaks

    View Slide

  83. View Slide