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

Optimizing For Readability

Optimizing For Readability

What do software engineers do all day long? Write code? Of course! But what about reading code, about understanding what’s happening? Aren’t we doing that even more? I believe we do. Because of that code should be as readable as possible! But what does that even mean? How do we achieve readable code? This talk will introduce you to coding principles and techniques that will help you write more readable code, be more productive and have more fun!

Tobias Pfeiffer

November 03, 2015
Tweet

More Decks by Tobias Pfeiffer

Other Decks in Programming

Transcript

  1. We write code

    View full-size slide

  2. Isn't it more
    about reading?

    View full-size slide

  3. Written once – read many
    times

    View full-size slide

  4. „(…) when you program, you have to think
    about how someone will read your code,
    not just how a computer will interpret it.“
    Kent Beck

    View full-size slide

  5. „Any fool can write code that a computer
    can understand. Good programmers write
    code that humans can understand.“
    Martin Fowler

    View full-size slide

  6. Not about architecture

    View full-size slide

  7. Methods & Code

    View full-size slide

  8. Nurturing a code base

    View full-size slide

  9. Extra effort

    View full-size slide

  10. Your code base?

    View full-size slide

  11. It's about joy!

    View full-size slide

  12. Optimizing for Readability
    Tobias Pfeiffer
    @PragTob
    pragtob.info

    View full-size slide

  13. Methods & Code

    View full-size slide

  14. Keep It Simple Stupid

    View full-size slide

  15. Are comments a smell?

    View full-size slide

  16. Comments are an excuse of
    the code that it could not be
    clearer.

    View full-size slide

  17. Outdated comments are the
    worst

    View full-size slide

  18. The why not the what

    View full-size slide

  19. def paint_control(event)
    # some painting code
    rescue => e
    # Really important to rescue here.
    Failures that escape this method
    # cause odd-ball hangs with no
    backtraces. See #559 for an example.
    #
    puts "SWALLOWED PAINT EXCEPTION ON
    #{@obj} - go take care of it: " + e.to_s
    puts 'Unfortunately we have to swallow
    it because it causes odd failures :('
    end

    View full-size slide

  20. Also known as the smell that
    tries to make other smells
    seem ok

    View full-size slide

  21. # do one thing
    ...
    ...
    ...
    ...
    ...
    # do another thing
    ...
    ...
    ...
    ...
    # do something more
    ...
    ...

    View full-size slide

  22. # do one thing
    ...
    ...
    ...
    ...
    ...
    # do another thing
    ...
    ...
    ...
    ...
    # do something more
    ...
    ...

    View full-size slide

  23. # do one thing
    ...
    ...
    ...
    ...
    ...
    # do another thing
    ...
    ...
    ...
    ...
    # do something more
    ...
    ...
    Cocepts

    View full-size slide

  24. Method too long

    View full-size slide

  25. Short Methods

    View full-size slide

  26. Extract Methods

    View full-size slide

  27. do_one_thing
    do_another_thing
    do_something_more
    Cocepts

    View full-size slide

  28. # context, outlet, times, time per
    step, state, data
    def pattern(c, o, t, l, s, d)
    # ...
    end

    View full-size slide

  29. Incomprehensible names

    View full-size slide

  30. # context, outlet, times, time per
    step, state, data
    def pattern(c, o, t, l, s, d)
    # ...
    end

    View full-size slide

  31. # context, outlet, times, time per
    step, state, data
    def pattern(c, o, t, l, s, d)
    # ...
    end

    View full-size slide

  32. Explanatory names

    View full-size slide

  33. Naming is hard

    View full-size slide

  34. def pattern(context, outlet, time,
    time_per_step, state,
    data)
    # ...
    end

    View full-size slide

  35. Argument order dependency

    View full-size slide

  36. Try to keep it to 2 parameters

    View full-size slide

  37. # allowed to drink?
    if customer.age >= 18
    say 'Okay'
    drink = prepare_drink requested_drink
    say 'here you go'
    hand_drink_over drink, customer
    else
    say 'I am sorry you are not legally
    allowed rather to drink here'
    say "Would you rather have a
    #{['cola', 'mate'].sample}?"
    end

    View full-size slide

  38. # allowed to drink?
    if customer.age >= 18
    say 'Okay'
    drink = prepare_drink requested_drink
    say 'here you go'
    hand_drink_over drink, customer
    else
    say 'I am sorry you are not legally
    allowed rather to drink here'
    say "Would you rather have a
    #{['cola', 'mate'].sample}?"
    end

    View full-size slide

  39. No magic numbers

    View full-size slide

  40. NON_ALCOHOLIC_DRINKS = ['cola', 'mate']
    MIN_DRINKING_AGE = 18

    View full-size slide

  41. # allowed to drink?
    if customer.age >= MIN_DRINKING_AGE
    say 'Okay'
    drink = prepare_drink requested_drink
    say 'here you go'
    hand_drink_over drink, customer
    else
    say 'I am sorry you are not legally
    allowed rather to drink here'
    say "Would you rather have a
    #{NON_ALCOHOLIC_DRINKS.sample}?"
    end

    View full-size slide

  42. # allowed to drink?
    if customer.age >= MIN_DRINKING_AGE
    say 'Okay'
    drink = prepare_drink requested_drink
    say 'here you go'
    hand_drink_over drink, customer
    else
    say 'I am sorry you are not legally
    allowed rather to drink here'
    say "Would you rather have a
    #{NON_ALCOHOLIC_DRINKS.sample}?"
    end

    View full-size slide

  43. # allowed to drink?
    if customer.age >= MIN_DRINKING_AGE
    say 'Okay'
    drink = prepare_drink requested_drink
    say 'here you go'
    hand_drink_over drink, customer
    else
    say 'I am sorry you are not legally
    allowed rather to drink here'
    say "Would you rather have a
    #{NON_ALCOHOLIC_DRINKS.sample}?"
    end

    View full-size slide

  44. Query method

    View full-size slide

  45. Intention revealing method

    View full-size slide

  46. # ...
    text.color = red
    # ...

    View full-size slide

  47. # ...
    text.color = red
    # ...

    View full-size slide

  48. # ...
    highlight(text)
    # ...

    View full-size slide

  49. def highlight(text)
    text.color = red
    end

    View full-size slide

  50. def highlight(text)
    text.color = red
    text.underline = true
    update_highlights
    end

    View full-size slide

  51. # ...
    text.color = red
    text.underline = true
    update_highlights
    # ...

    View full-size slide

  52. # ...
    highlight(text)
    # ...

    View full-size slide

  53. # allowed to drink?
    if customer.age >= MIN_DRINKING_AGE
    say 'Okay'
    drink = prepare_drink requested_drink
    say 'here you go'
    hand_drink_over drink, customer
    else
    say 'I am sorry you are not legally
    allowed rather to drink here'
    say "Would you rather have a
    #{NON_ALCOHOLIC_DRINKS.sample}?"
    end

    View full-size slide

  54. # allowed to drink?
    if customer.age >= MIN_DRINKING_AGE
    say 'Okay'
    drink = prepare_drink requested_drink
    say 'here you go'
    hand_drink_over drink, customer
    else
    say 'I am sorry you are not legally
    allowed rather to drink here'
    say "Would you rather have a
    #{NON_ALCOHOLIC_DRINKS.sample}?"
    end

    View full-size slide

  55. # allowed to drink?
    if customer.age >= MIN_DRINKING_AGE
    say 'Okay'
    drink = prepare_drink requested_drink
    say 'here you go'
    hand_drink_over drink, customer
    else
    say 'I am sorry you are not legally
    allowed rather to drink here'
    say "Would you rather have a
    #{NON_ALCOHOLIC_DRINKS.sample}?"
    end

    View full-size slide

  56. # allowed to drink?
    if customer.age >= MIN_DRINKING_AGE
    say 'Okay'
    drink = prepare_drink requested_drink
    say 'here you go'
    hand_drink_over drink, customer
    else
    say 'I am sorry you are not legally
    allowed rather to drink here'
    say "Would you rather have a
    #{NON_ALCOHOLIC_DRINKS.sample}?"
    end

    View full-size slide

  57. if allowed_to_drink_alcohol?(customer)
    serve_drink requested_drink,
    customer
    else
    propose_non_alcoholic_drink
    end

    View full-size slide

  58. „If you have a good name for
    a method you don't need to
    look at the body.“
    Martin Fowler

    View full-size slide

  59. „The easiest code to
    understand is the code you
    don't have to read at all.“
    Tom Stuart (Berlin)

    View full-size slide

  60. prepare_drink requested_drink
    price = requested_drink.price
    check = Check.new
    check.add_price price
    say 'That whill be ' + check.total

    View full-size slide

  61. prepare_drink requested_drink
    price = requested_drink.price
    check = Check.new
    check.add_price price
    say 'That whill be ' + check.total

    View full-size slide

  62. prepare_drink requested_drink
    price = requested_drink.price
    check = Check.new
    check.add_price price
    say 'That whill be ' + check.total

    View full-size slide

  63. Same level of abstraction in
    a method

    View full-size slide

  64. prepare_drink requested_drink
    prepare_check requested_drink

    View full-size slide

  65. Nice code formatting

    View full-size slide

  66. @left ||= 0
    @top ||= 0
    @width ||= 1.0
    @height ||= 0

    View full-size slide

  67. double character: 'something weird',
    stateMask: CTRL | modifier,
    KeyCode: character.downcase.ord

    View full-size slide

  68. 80 character width limit

    View full-size slide

  69. 80 character width limit

    View full-size slide

  70. 80 character width limit

    View full-size slide

  71. 80 character width limit

    View full-size slide

  72. 80 character width limit

    View full-size slide

  73. Identify concepts

    View full-size slide

  74. One language

    View full-size slide

  75. Don't Repeat Yourself

    View full-size slide

  76. Nurturing a code base

    View full-size slide

  77. Code bases detoriate

    View full-size slide

  78. No broken windows!

    View full-size slide

  79. Magical time?

    View full-size slide

  80. The boyscout rule

    View full-size slide

  81. Opportunistic Refactoring

    View full-size slide

  82. 80% Code Coverage

    View full-size slide

  83. 20% is never executed

    View full-size slide

  84. Code Review Culture

    View full-size slide

  85. „Brown Bag“ lunches

    View full-size slide

  86. Pair Programming

    View full-size slide

  87. Reaping the benefits

    View full-size slide

  88. Know when to break the rules

    View full-size slide

  89. If you still like your code from
    two years ago,
    then you are not learning fast
    enough.

    View full-size slide

  90. Enjoy writing readable code!
    Tobias Pfeiffer
    @PragTob
    pragtob.info

    View full-size slide

  91. Sources

    The Pragmatic Programmer

    Smalltalk Best Practice Patterns

    Clean Code

    Practical Object Oriented Design in Ruby

    View full-size slide

  92. Photo Credit

    http://officeimg.vo.msecnd.net/en-us/images/MP900439313.jpg

    http://officeimg.vo.msecnd.net/en-us/images/MC900021328.wmf

    http://www.osnews.com/story/19266/WTFs_m

    (CC BY-SA 2.0)
    – http://www.flickr.com/photos/83633410@N07/7658272558/in/photostream/
    – http://www.flickr.com/photos/83633410@N07/7658165122/
    – https://www.flickr.com/photos/93425126@N00/313056379/

    (CC BY-NC-ND 2.0)
    – http://www.flickr.com/photos/andih/86577529/
    – http://www.flickr.com/photos/12584908@N08/3293117576/
    – http://www.flickr.com/photos/jasonlparks/4525188865/
    – http://www.flickr.com/photos/20714221@N04/2293045156/
    – https://www.flickr.com/photos/eyewash/2603717864/
    – https://www.flickr.com/photos/stevie_gill/3950697539/
    – https://www.flickr.com/photos/randar/15787696685/

    http://www.flickr.com/photos/47833351@N02/5488791911/(CC BY-ND 2.0)

    (CC BY 2.0)
    – http://www.flickr.com/photos/barry_b/76055201/
    – http://www.flickr.com/photos/25165196@N08/7725273678/
    – http://www.flickr.com/photos/29254399@N08/3187186308/
    – https://www.flickr.com/photos/garryknight/5650367750/
    – https://www.flickr.com/photos/alper/10742816123/

    (CC BY-NC-SA 2.0)
    – http://www.flickr.com/photos/dolescum/7380616658/
    – http://www.flickr.com/photos/antonkovalyov/5795281215/
    – http://www.flickr.com/photos/doug88888/2792209612/
    – https://www.flickr.com/photos/denverjeffrey/4392418334/

    (CC BY-NC 2.0)
    – http://www.flickr.com/photos/37996583811@N01/5757983532/
    – http://www.flickr.com/photos/sevendead/5650065458/
    – https://www.flickr.com/photos/whitecatsg/3146092196/

    View full-size slide