Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.
Arjan van Leeuwen
The Evolution of
Good Code
ACCU 2014
@avl7771
Take one of each
! !
"The past is a foreign
country: they do things
differently there."
— L.P. Hartley
GoodSolidReadable
MaintainableElegant
Bug-free
reliableTestable
Debuggable CLEAN
The bookshelf
“A man may as well expect to
grow stronger by always eating
as wiser by always reading.”!
— Jeremy Collier
Writing Solid Code
❖ Steve Maguire!
❖ Microsoft Programming!
❖ 1993!
❖ “Microsoft’s Techniques for
Developing Bug-Free C
P...
The Pragmatic Programmer
❖ Andrew Hunt & David
Thomas!
❖ Addison Wesley!
❖ 2000!
❖ “examines the core process -
taking a r...
Code Complete
❖ Steve McConnell!
❖ Microsoft Programming!
❖ 2004 (1st Edition 1993)!
❖ “A Practical Handbook of
Software C...
Clean Code
❖ Robert C. Martin (“Uncle Bob”)!
❖ Prentice Hall!
❖ 2009!
❖ “A handbook for Agile Software
Craftsmanship” — “H...
97 Things Every Programmer Should Know
❖ Various Artists, edited by
Kevlin Henney!
❖ O’Reilly!
❖ 2010!
❖ “Collective Wisdo...
Growing Object-Oriented Software, Guided by Tests
❖ Steve Freeman & Nat Pryce!
❖ Addison Wesley!
❖ 2010!
❖ “Two TDD pionee...
The Art of Readable Code
❖ Dustin Boswell & Trevor
Foucher!
❖ O’Reilly!
❖ 2011!
❖ “Simple and Practical Techniques
for Wri...
Guess the book!
“If we encounter a man of rare
intellect, we should ask him what
books he reads.”!
— Ralph Waldo Emerson
2011
2009
! ! 1993
Use Hungarian notation for variables
❖ “Although names like pch look
funny and are hard to
pronounce, t...
! ! 1993
Use Hungarian notation for variables
❖ “Although names like pch look
funny and are hard to
pronounce, they are fil...
Don’t use Hungarian notation for variables
❖ “In modern languages we have
much richer type systems, and
the compilers reme...
Don’t use Hungarian notation for variables
❖ “In modern languages we have
much richer type systems, and
the compilers reme...
2004
Don’t use Yoda Conditions
❖ “Putting constants and
expressions on the left-hand
side of comparisons works
only when o...
Don’t use Yoda Conditions
❖ “Putting constants and
expressions on the left-hand
side of comparisons works
only when one of...
2010
Enforce singletons
❖ “If you want to define a class
that allows only one object to
be instantiated, enforce this by
hi...
Enforce singletons
❖ “If you want to define a class
that allows only one object to
be instantiated, enforce this by
hiding ...
2011
Prefer Write-Once Variables
❖ “The more places a variable is
manipulated, the harder it is to
reason about its curren...
2011
Prefer Write-Once Variables
❖ “The more places a variable is
manipulated, the harder it is to
reason about its curren...
2011
Design for Unit Tests
❖ “Most important, is it possible
to automatically and
thoroughly validate the design
using a u...
Design for Unit Tests
❖ “Most important, is it possible
to automatically and
thoroughly validate the design
using a unit t...
Names and aesthetics Small changes that help you
understand code
Use Hungarian Notation for Variables
❖ Prefix indicates type or intended use!
❖ Widely used after use in Microsoft Windows ...
Why?
❖ Makes wrong code ‘look wrong’ [Maguire93], [McConnell04]!
❖ Easy to decipher pointer expressions [McConnell04]!
❖ S...
Why not?
❖ Encoding adds burden of deciphering [Martin09]!
❖ Not necessary for types anymore [Martin09]!
❖ Functions and c...
Use Hungarian Notation for Variables
1993 2000 2004 2009 2011
Specify interface or implementation in class name
❖ Denote in the class name when a class is an interface or
when it imple...
Why?
❖ See whether you are using an interface just from the
name
Why not?
❖ Users shouldn’t (have to) know they’re dealing with an
interface, better to encode the Impl [Martin09]!
❖ Names...
Specify interface or implementation in class name
1993 2004 2009 2010
? ?
Align similar statements
❖ Can be used wherever similar statements are done on
multiple lines!
❖ Purely aesthetic enhancem...
Why?
❖ Alignment scheme shows statements belong together
[McConnell93]!
❖ Neater listing and quicker scanning [McConnell93...
Why not?
❖ A headache to maintain as names change and lines are
moved amongst different indentations [McConnell04]!
❖ Emph...
Align similar statements
1993 2004 2009 2011
Keep functions short
❖ Functions should be as small as possible
std::string renderPageWithSetupsAndTeardowns(
PageData pag...
Why?
❖ Easier to read and understand [Martin09]!
❖ Documentary value (descriptive name) [Martin09]!
❖ Easier to improve fu...
Why not?
❖ Routines of longer length are no more error prone than
shorter routines, shorter may have more errors [McConnel...
Keep functions short
1993 2004 2009 2011
Simplifying Logic Or: how to write less
Don’t Repeat Yourself (DRY)
❖ Every piece of code must have a single, unambiguous,
authoritative representation within a s...
Why?
❖ Change in one will make two implementations diverge
[Hunt00]!
❖ Similar code in two routines implies an error in
de...
Don’t Repeat Yourself (DRY)
1993 2000 2009 2011
Early Return
❖ Use guard clauses to return early for exceptional or
error conditions!
❖ Return early from e.g. linear sear...
Why?
❖ Implementing without guard clauses unnatural [Boswell11]!
❖ Avoids deep nesting [McConnell04], [Boswell11]!
❖ Singl...
Why not?
❖ Breaks Structured Programming single-entry, single exit
‘law’ [Martin09]!
❖ Harder to understand a routine when...
Early Return
1993 2000 2004 2009 2011
Prefer Exceptions to Returning Error Codes
❖ Use exceptions to clarify the control flow
try {
socket.read(name);
process(na...
Why?
❖ Clarifies normal flow of control [Hunt00]!
❖ Avoids violation of command query separation [Martin09]!
❖ Don’t force u...
Why not?
❖ High-level program flow obscured by bubbling up
[Boswell11]!
❖ Alternative error handling often more appropriate...
Prefer Exceptions to Returning Error Codes
2000 2004 2009 2011
Tell, Don’t Ask
❖ Objects make their decisions based only on the
information they hold internally or that which came
with ...
Why?
❖ Produces more flexible code, easier to swap objects
[Freeman10]!
❖ Hides internal structure [Freeman10], [Martin09]!...
Tell, Don’t Ask
2000 2004 2009 2010
Reliability, Debugging
and Testing
Use Functional Programming Principles
❖ Use knowledge of functional programming in
imperative languages!
❖ Work with immut...
Why?
❖ Avoid side effects [Garson10]!
❖ Simpler to debug (source of change easy to find) [Garson10]!
❖ Avoid thread race co...
Use Functional Programming Principles
1993 2004 2010 2011 2012
? ?
Use Functional Programming Principles
1993 2004 2010 2011 2012
? ?
Program in Terms of the Problem Domain
❖ Model types and behavior in terms of the programming
problem rather than the comp...
Why?
❖ Increases code readability and understanding [North10]!
❖ Can evolve code when domain model evolves [North10]!
❖ Wo...
Why not?
❖ The people who read your code are programmers: they
know CS terms [Martin09]
Program in Terms of the Problem Domain
1993 2000 2004 2009 2010
Prefer Message-Passing in Parallel Systems
❖ Use message passing instead of shared mutable
variables!
❖ Use copies of data...
Why?
❖ Shared mutable memory is at the root of problems
related to concurrency: race conditions, deadlock,
livelock [Winde...
Prefer Message-Passing in Parallel Systems
1993 2004 2009 2010
? ?
Step Through your Code in a Debugger
❖ Actively step through all new or modified code to watch
it execute!
❖ As you step th...
Why?
❖ Allows you to get a ‘feeling’ for the code and gain
confidence [Maguire93]!
❖ You could create tests, but debugging ...
Why not?
❖ Problems can be found more quickly and more
accurately by thinking [McConnell04]!
❖ A bug should be reproducibl...
Step Through your Code in a Debugger
1993 2004 2009 2011
??
Test-Friendly Development
❖ Design your code so that it’s easy to test!
❖ Avoid use of global state!
❖ Avoid coupling
Why?
❖ Easier to test [Everyone]!
❖ Test-friendly code leads naturally to well-organized
code [Boswell11]!
❖ Decoupling le...
Why not?
❖ Could sacrifice readability for the sake of enabling tests
[Boswell11]!
❖ Testing by itself does not improve sof...
Test-Friendly Development
1993 2000 2004 2009 2011
Test-Driven Development
❖ Write test cases before writing code!
❖ Follow Red-Green-Refactor cycle!
❖ Do not write code wit...
Why?
❖ Forces you to think about requirements and design of
the code, finds problems earlier [McConnell04]!
❖ Tests will co...
Why not?
❖ Can create false sense of security (should not be only
form of testing) [McConnell04]!
❖ Just keeping testing i...
Test-Driven Development
1993 2004 2009 2010 2011
?
Boy Scout Rule
❖ “Always leave the campground cleaner than you found
it”!
❖ When you check in a module, make a small
impro...
Why?
❖ The end of deterioration of software systems [Martin10]!
❖ Systems gradually get better [Martin10]!
❖ Promotes coll...
Why not?
❖ What kind of motto is “If it ain’t broke, fix it anyway”?
[Maguire93]!
❖ Programmers don’t treat improved code a...
Boy Scout Rule
1993 2004 2009 2010
Conclusion
“The word is about,!
there's something evolving,!
whatever may come,!
the world keeps revolving!
!
They say the...
Conclusion
❖ (Better) unit testing and test-driven development have
an impact on other practices!
❖ Concurrency finally hav...
References
❖ [Boswell11] Dustin Boswell, Trevor Forcher, “The Art of Readable Code”. O’Reilly, 2011.!
❖ [Carmack12] John C...
Prochain SlideShare
Chargement dans…5
×

The Evolution of Good Code

3 109 vues

Publié le

A talk describing how best practices for writing code have changed throughout the last 21 years.

What do we think of as good code, and how has our perception of good code changed form the early days of programming to the exciting times we live in now?

In this talk we do a bit of digging into the short history of programming, by looking at the available literature and various best practices promoted throughout the ages to improve your code.

Publié dans : Logiciels, Technologie, Formation
  • Soyez le premier à commenter

The Evolution of Good Code

  1. 1. Arjan van Leeuwen The Evolution of Good Code ACCU 2014 @avl7771
  2. 2. Take one of each ! !
  3. 3. "The past is a foreign country: they do things differently there." — L.P. Hartley
  4. 4. GoodSolidReadable MaintainableElegant Bug-free reliableTestable Debuggable CLEAN
  5. 5. The bookshelf “A man may as well expect to grow stronger by always eating as wiser by always reading.”! — Jeremy Collier
  6. 6. Writing Solid Code ❖ Steve Maguire! ❖ Microsoft Programming! ❖ 1993! ❖ “Microsoft’s Techniques for Developing Bug-Free C Programs”
  7. 7. The Pragmatic Programmer ❖ Andrew Hunt & David Thomas! ❖ Addison Wesley! ❖ 2000! ❖ “examines the core process - taking a requirement and producing working, maintainable code that delights its users”
  8. 8. Code Complete ❖ Steve McConnell! ❖ Microsoft Programming! ❖ 2004 (1st Edition 1993)! ❖ “A Practical Handbook of Software Construction” - “Helps you build the highest quality code”
  9. 9. Clean Code ❖ Robert C. Martin (“Uncle Bob”)! ❖ Prentice Hall! ❖ 2009! ❖ “A handbook for Agile Software Craftsmanship” — “How to write good code and how to transform bad code into good code”
  10. 10. 97 Things Every Programmer Should Know ❖ Various Artists, edited by Kevlin Henney! ❖ O’Reilly! ❖ 2010! ❖ “Collective Wisdom from the Experts” — “you’ll expand your skills by … learning appropriate best practices”
  11. 11. Growing Object-Oriented Software, Guided by Tests ❖ Steve Freeman & Nat Pryce! ❖ Addison Wesley! ❖ 2010! ❖ “Two TDD pioneers show how to let tests guide your development and ‘grow’ software that is coherent, reliable, and maintainable”
  12. 12. The Art of Readable Code ❖ Dustin Boswell & Trevor Foucher! ❖ O’Reilly! ❖ 2011! ❖ “Simple and Practical Techniques for Writing Better Code”
  13. 13. Guess the book! “If we encounter a man of rare intellect, we should ask him what books he reads.”! — Ralph Waldo Emerson
  14. 14. 2011 2009 ! ! 1993 Use Hungarian notation for variables ❖ “Although names like pch look funny and are hard to pronounce, they are filled with information.”! ❖ “Conveying information is far more important in naming your variables than being able to stand up and read your code aloud during a program review.” /* pointer to character pointer */ char **ppch;
  15. 15. ! ! 1993 Use Hungarian notation for variables ❖ “Although names like pch look funny and are hard to pronounce, they are filled with information.”! ❖ “Conveying information is far more important in naming your variables than being able to stand up and read your code aloud during a program review.” /* pointer to character pointer */ char **ppch;
  16. 16. Don’t use Hungarian notation for variables ❖ “In modern languages we have much richer type systems, and the compilers remember and enforce the types.”! ❖ “Nowadays HN and other forms of type encoding are simply impediments. They make it harder to read the code.” /* pointer to character pointer */ char **ppch; 2011 2009 ! ! 1993
  17. 17. Don’t use Hungarian notation for variables ❖ “In modern languages we have much richer type systems, and the compilers remember and enforce the types.”! ❖ “Nowadays HN and other forms of type encoding are simply impediments. They make it harder to read the code.” /* pointer to character pointer */ char **ppch; 2009
  18. 18. 2004 Don’t use Yoda Conditions ❖ “Putting constants and expressions on the left-hand side of comparisons works only when one of the operands is a constant or an expression.”! ❖ “If instead you use a compiler switch, the compiler would alert you to every possible assignment bug.” 2011 ! ! 1993 if (10 == x) // if 10, x is!
  19. 19. Don’t use Yoda Conditions ❖ “Putting constants and expressions on the left-hand side of comparisons works only when one of the operands is a constant or an expression.”! ❖ “If instead you use a compiler switch, the compiler would alert you to every possible assignment bug.” if (10 == x) // if 10, x is! ! ! 1993
  20. 20. 2010 Enforce singletons ❖ “If you want to define a class that allows only one object to be instantiated, enforce this by hiding all the constructors of the class and providing a static routine to access the class’s single instance.” public class MaxId { private MaxId() {} public static MaxId GetInstance() { /*..*/ } } 2004 ! ! 1993
  21. 21. Enforce singletons ❖ “If you want to define a class that allows only one object to be instantiated, enforce this by hiding all the constructors of the class and providing a static routine to access the class’s single instance.” public class MaxId { private MaxId() {} public static MaxId GetInstance() { /*..*/ } } 2004
  22. 22. 2011 Prefer Write-Once Variables ❖ “The more places a variable is manipulated, the harder it is to reason about its current value”! ❖ “Variables that are a ‘permanent fixture’ are easier to think about”! ❖ “Immutables tend to more often be trouble-free” 2004 ! ! 2000
  23. 23. 2011 Prefer Write-Once Variables ❖ “The more places a variable is manipulated, the harder it is to reason about its current value”! ❖ “Variables that are a ‘permanent fixture’ are easier to think about”! ❖ “Immutables tend to more often be trouble-free”
  24. 24. 2011 Design for Unit Tests ❖ “Most important, is it possible to automatically and thoroughly validate the design using a unit test? If not, you should consider using an alternative design that can be tested.” 2004 ! ! 1993
  25. 25. Design for Unit Tests ❖ “Most important, is it possible to automatically and thoroughly validate the design using a unit test? If not, you should consider using an alternative design that can be tested.” ! ! 1993
  26. 26. Names and aesthetics Small changes that help you understand code
  27. 27. Use Hungarian Notation for Variables ❖ Prefix indicates type or intended use! ❖ Widely used after use in Microsoft Windows C libraries! ❖ “Systems Hungarian” vs. “Apps Hungarian” char ch; /* a plain old character */ bool f; /* flags that are always TRUE or FALSE */ char *pch; /* a character pointer */ char **ppch; /* pointer to a character pointer */ char *szName; /* a zero-terminated string */
  28. 28. Why? ❖ Makes wrong code ‘look wrong’ [Maguire93], [McConnell04]! ❖ Easy to decipher pointer expressions [McConnell04]! ❖ Semantic prefixes add information that compiler doesn’t know about [McConnell04]! ❖ Standardized prefixes encourage consistent naming [McConnell04]
  29. 29. Why not? ❖ Encoding adds burden of deciphering [Martin09]! ❖ Not necessary for types anymore [Martin09]! ❖ Functions and classes are shorter now [Martin09]! ❖ Inappropriate in object-oriented systems [Hunt00]! ❖ Code is read more than it’s written [Hunt00]
  30. 30. Use Hungarian Notation for Variables 1993 2000 2004 2009 2011
  31. 31. Specify interface or implementation in class name ❖ Denote in the class name when a class is an interface or when it implements an interface! ❖ Typically using prefix ‘I’ for Interface and/or postfix ‘Impl’ for Implementation class IBloober { virtual void blob() = 0; }; ! class BlooberImpl : public IBloober { virtual void blob(); };
  32. 32. Why? ❖ See whether you are using an interface just from the name
  33. 33. Why not? ❖ Users shouldn’t (have to) know they’re dealing with an interface, better to encode the Impl [Martin09]! ❖ Names ending in Impl duplicate information [Freeman10]! ❖ Can indicate poorly named interface or design [Freeman10]
  34. 34. Specify interface or implementation in class name 1993 2004 2009 2010 ? ?
  35. 35. Align similar statements ❖ Can be used wherever similar statements are done on multiple lines! ❖ Purely aesthetic enhancement customerPurchases = customerPurchases + CustomerSales(customerID); customerBill = customerBill + customerPurchases; totalCustomerBill = customerBill + PreviousBalance(customerID) + LateCharge(customerID); customerRating = Rating(customerID, totalCustomerBill);
  36. 36. Why? ❖ Alignment scheme shows statements belong together [McConnell93]! ❖ Neater listing and quicker scanning [McConnell93]! ❖ Column edges provide “visual handrails” [Boswell11]! ❖ Doesn’t take much work [Boswell11]
  37. 37. Why not? ❖ A headache to maintain as names change and lines are moved amongst different indentations [McConnell04]! ❖ Emphasizes wrong things [Martin09]! ❖ Keep lists short [Martin09]! ❖ Eliminated by automatic reformatting tools [Martin09]
  38. 38. Align similar statements 1993 2004 2009 2011
  39. 39. Keep functions short ❖ Functions should be as small as possible std::string renderPageWithSetupsAndTeardowns( PageData pageData, bool isSuite) { if (isTestPage(pageData)) includeSetupAndTeardownPages(pageData, isSuite); return pageData.getHtml(); }
  40. 40. Why? ❖ Easier to read and understand [Martin09]! ❖ Documentary value (descriptive name) [Martin09]! ❖ Easier to improve function when the code is by itself [Boswell11]
  41. 41. Why not? ❖ Routines of longer length are no more error prone than shorter routines, shorter may have more errors [McConnell93], [McConnell04]! ❖ Routines of longer length are cheaper to develop [McConnell93], [McConnell04]! ❖ Tiny functions can hurt readability [Boswell11]
  42. 42. Keep functions short 1993 2004 2009 2011
  43. 43. Simplifying Logic Or: how to write less
  44. 44. Don’t Repeat Yourself (DRY) ❖ Every piece of code must have a single, unambiguous, authoritative representation within a system [Hunt00]
  45. 45. Why? ❖ Change in one will make two implementations diverge [Hunt00]! ❖ Similar code in two routines implies an error in decomposition [McConnell93]! ❖ Duplication is a missed opportunity for abstraction [Martin09]! ❖ Duplication can indicate bad design [Hunt00]! ❖ Copy/Paste programming is bad, remember Y2K [Hunt00]
  46. 46. Don’t Repeat Yourself (DRY) 1993 2000 2009 2011
  47. 47. Early Return ❖ Use guard clauses to return early for exceptional or error conditions! ❖ Return early from e.g. linear search when a result is found public boolean Contains(String str, String substr) { if (str == null || substr == null) return false; if (substr.equals("")) return true; ... }
  48. 48. Why? ❖ Implementing without guard clauses unnatural [Boswell11]! ❖ Avoids deep nesting [McConnell04], [Boswell11]! ❖ Single exit point less important with shorter functions [Martin09]! ❖ Single exit point less important with modern languages [Boswell11]
  49. 49. Why not? ❖ Breaks Structured Programming single-entry, single exit ‘law’ [Martin09]! ❖ Harder to understand a routine when unaware of all return points [McConnell93]
  50. 50. Early Return 1993 2000 2004 2009 2011
  51. 51. Prefer Exceptions to Returning Error Codes ❖ Use exceptions to clarify the control flow try { socket.read(name); process(name); socket.read(address); processAddress(address); socket.read(telNo) // etc, etc... } catch (IOException e) { Logger.log("Error reading individual: " + e.getMessage()); }
  52. 52. Why? ❖ Clarifies normal flow of control [Hunt00]! ❖ Avoids violation of command query separation [Martin09]! ❖ Don’t force user to handle error immediately [Martin09]! ❖ Signal errors in a way that cannot be ignored [McConnell04]
  53. 53. Why not? ❖ High-level program flow obscured by bubbling up [Boswell11]! ❖ Alternative error handling often more appropriate [McConnell04]! ❖ Exceptions should only be used in exceptional situations (that should never happen) [Hunt00]
  54. 54. Prefer Exceptions to Returning Error Codes 2000 2004 2009 2011
  55. 55. Tell, Don’t Ask ❖ Objects make their decisions based only on the information they hold internally or that which came with the triggering message [Freeman10] ((EditSaveCustomizer) master.getModelisable() .getDockablePanel() .getCustomizer() .getSaveItem().setEnabled(Boolean.FALSE.booleanValue()); ! // becomes... master.allowSavingOfCustomisations();
  56. 56. Why? ❖ Produces more flexible code, easier to swap objects [Freeman10]! ❖ Hides internal structure [Freeman10], [Martin09]! ❖ Avoids train wrecks [Freeman10], [Martin09]! ❖ Minimizes coupling [Hunt00]
  57. 57. Tell, Don’t Ask 2000 2004 2009 2010
  58. 58. Reliability, Debugging and Testing
  59. 59. Use Functional Programming Principles ❖ Use knowledge of functional programming in imperative languages! ❖ Work with immutable data and pure functions where possible
  60. 60. Why? ❖ Avoid side effects [Garson10]! ❖ Simpler to debug (source of change easy to find) [Garson10]! ❖ Avoid thread race conditions [Carmack12]! ❖ The more places a variable is manipulated, the harder it is to reason about its value [Boswell11]
  61. 61. Use Functional Programming Principles 1993 2004 2010 2011 2012 ? ?
  62. 62. Use Functional Programming Principles 1993 2004 2010 2011 2012 ? ?
  63. 63. Program in Terms of the Problem Domain ❖ Model types and behavior in terms of the programming problem rather than the computer science solution if (portfolioIdsByTraderId.get(trader.getId()) .containsKey(portfolio.getId())) { ... } ! // becomes ... if (trader.canView(portfolio)) { ... }
  64. 64. Why? ❖ Increases code readability and understanding [North10]! ❖ Can evolve code when domain model evolves [North10]! ❖ Work at a higher level of abstraction to allow focusing on solving domain problems [Hunt00]! ❖ Hides low-level details [McConnell93]! ❖ Separating solution and problem domain is part of the job of a good programmer [Martin09]
  65. 65. Why not? ❖ The people who read your code are programmers: they know CS terms [Martin09]
  66. 66. Program in Terms of the Problem Domain 1993 2000 2004 2009 2010
  67. 67. Prefer Message-Passing in Parallel Systems ❖ Use message passing instead of shared mutable variables! ❖ Use copies of data where necessary! ❖ If the language doesn’t provide it, use libraries or frameworks that do
  68. 68. Why? ❖ Shared mutable memory is at the root of problems related to concurrency: race conditions, deadlock, livelock [Winder10]! ❖ Proven way of handling concurrency [Winder10]! ❖ Avoiding synchronization makes up for overhead [Martin09]
  69. 69. Prefer Message-Passing in Parallel Systems 1993 2004 2009 2010 ? ?
  70. 70. Step Through your Code in a Debugger ❖ Actively step through all new or modified code to watch it execute! ❖ As you step through code, focus on data flow! ❖ Step through every code path
  71. 71. Why? ❖ Allows you to get a ‘feeling’ for the code and gain confidence [Maguire93]! ❖ You could create tests, but debugging is much faster [Maguire93]
  72. 72. Why not? ❖ Problems can be found more quickly and more accurately by thinking [McConnell04]! ❖ A bug should be reproducible with a single command [Hunt00]
  73. 73. Step Through your Code in a Debugger 1993 2004 2009 2011 ??
  74. 74. Test-Friendly Development ❖ Design your code so that it’s easy to test! ❖ Avoid use of global state! ❖ Avoid coupling
  75. 75. Why? ❖ Easier to test [Everyone]! ❖ Test-friendly code leads naturally to well-organized code [Boswell11]! ❖ Decoupling leads to easier refactoring [Boswell11]! ❖ Classes with less state are simpler and easier to understand [Boswell11]! ❖ Designing to test promotes reusability [Hunt00]
  76. 76. Why not? ❖ Could sacrifice readability for the sake of enabling tests [Boswell11]! ❖ Testing by itself does not improve software quality [McConnell93], [McConnell04]
  77. 77. Test-Friendly Development 1993 2000 2004 2009 2011
  78. 78. Test-Driven Development ❖ Write test cases before writing code! ❖ Follow Red-Green-Refactor cycle! ❖ Do not write code without having test cases
  79. 79. Why? ❖ Forces you to think about requirements and design of the code, finds problems earlier [McConnell04]! ❖ Tests will cover virtually all production code [Martin09]! ❖ Creates short feedback cycle in development [Freeman10]! ❖ Integrates refactoring in development [Freeman10]! ❖ Takes same amount of time as creating tests afterwards [McConnell04]
  80. 80. Why not? ❖ Can create false sense of security (should not be only form of testing) [McConnell04]! ❖ Just keeping testing in mind can help improve the code [Boswell11]! ❖ Testing can get in the way of product development [Boswell11]
  81. 81. Test-Driven Development 1993 2004 2009 2010 2011 ?
  82. 82. Boy Scout Rule ❖ “Always leave the campground cleaner than you found it”! ❖ When you check in a module, make a small improvement, regardless of who the original author was
  83. 83. Why? ❖ The end of deterioration of software systems [Martin10]! ❖ Systems gradually get better [Martin10]! ❖ Promotes collective ownership [Martin10]! ❖ Don’t be afraid of the code [Lewis10]
  84. 84. Why not? ❖ What kind of motto is “If it ain’t broke, fix it anyway”? [Maguire93]! ❖ Programmers don’t treat improved code as if it were new code [Maguire93]! ❖ Your colleagues are not bozos, they might have had their reasons [Maguire93]! ❖ Change in itself is not a virtue [McConnell04]
  85. 85. Boy Scout Rule 1993 2004 2009 2010
  86. 86. Conclusion “The word is about,! there's something evolving,! whatever may come,! the world keeps revolving! ! They say the next big thing is here,! that the revolution's near,! but to me it seems quite clear! that it's all just a little bit of history repeating”! ! —Alex Gifford by way of Shirley Bassey Arjan van Leeuwen / @avl7771
  87. 87. Conclusion ❖ (Better) unit testing and test-driven development have an impact on other practices! ❖ Concurrency finally having an impact, comeback of functional language principles! ❖ Many practices that might seem recent were in fact known for a long time
  88. 88. References ❖ [Boswell11] Dustin Boswell, Trevor Forcher, “The Art of Readable Code”. O’Reilly, 2011.! ❖ [Carmack12] John Carmack, “Functional Programming in C++”. http://www.altdevblogaday.com/2012/04/26/functional- programming-in-c/, 2012.! ❖ [Freeman10] Steve Freeman, Nat Pryce, “Growing Object-Oriented Software”. Addison-Wesley, 2010.! ❖ [Garson10] Edward Garson, “Apply Functional Programming Principles”, from “97 Things Every Programmer Should Know”. O’Reilly, 2010.! ❖ [Hunt00] Andrew Hunt, David Thomas, “The Pragmatic Programmer”. Addison-Wesley, 2000.! ❖ [Maguire93] Stephen A. Maguire, “Writing Solid Code”. Microsoft Press, 1993! ❖ [Martin09] Robert C. Martin, “Clean Code”. Prentice Hall, 2009.! ❖ [McConnell93] Steve McConnell, “Code Complete”. Microsoft Press, 1993! ❖ [McConnell04] Steve McConnell, “Code Complete 2”. Microsoft Press, 2004.! ❖ [North10] Dan North, “Code in the Language of the Domain”, from “97 Things Every Programmer Should Know”. O’Reilly, 2010.! ❖ [Winder10] Russel Winder, “Message Passing Leads to Better Scalability in Parallel Systems”, from “97 Things Every Programmer Should Know”. O’Reilly, 2010.

×