The problem that new technology doesn’t fix is unmaintainable code. Clean code with good tests is essential, but not enough. This talk introduces techniques like getting better at naming, explaining code with tests, the few code comments you actually need, README-driven development and writing Minimum Viable Documentation. After the excitement of adopting new technology and software craftsmanship comes the horror of your next software maintenance project. As Jean-Paul Sartre said*, ‘Hell is other people’s code’. Whatever your level, your future happiness depends on maintainable code.
5. Scott Edmunds / CC BY 2.0
Modern
languages give
you all the toys
6. Modern languages’ maintainable code problem
1. OOP and FP at the same time
2. Exceptionally expressive programming language
3. Rapid language development - major changes
4. Early-adopter culture
5. Computer science vs mathematics vs enterprise dev
(a rich community but sometimes with conflicting goals)
6@PeterHilton •
7.
8. Causes of unmaintainable code
We’re lazy.
We’re too clever for our own good.
(functional programmers especially)
We should stop starting things and start finishing things
(especially refactoring)
8@PeterHilton •
9. Consequences of unmaintainable code
1. Higher cost to develop a new feature or fix a bug
2. Developers become unhappy and leave
3. Higher cost to hire new developers
4. Fewer good developers on the team
5. Code gets less maintainable
6. Go back to step 1 - enjoy the descent into legacy code hell
9@PeterHilton •
11. 11@PeterHilton •
1. Learn how to write
unmaintainable code*
2. Don’t do that!
* How To Write Unmaintainable Code,
Roedy Green, Canadian Mind Products
https://github.com/Droogans/unmaintainable-code
12. Marks of unmaintainable code
1. Inconsistent code styles (OOP vs FP, Java vs Haskell)
2. Repetition
3. Too much abstraction (unnameable invented concepts)
4. Spaghetti code
5. Lasagne architecture (too many layers)
6. Inadequate tests (low coverage, incomprehensible)
12@PeterHilton •
13. Use a consistent coding style
Pick one way to use/avoid FP and OOP, and stick to it.
This is easy, provided that you never:
1. learn anything new about your language
2. learn anything new about functional programming
3. learn anything new about programming
4. move to a newer language version
5. work with other people who have different backgrounds
13@PeterHilton •
14.
15. @PeterHilton •
Learning to write clean code
is the first step towards
maintainable code
There’s a book for that!
However, the book isn’t
perfect and doesn’t target
Scala.
15
16. Naming things
16@PeterHilton •
Good names for everything are the key to clean code
How hard can it be?*
Use software tools, practice, get better at it.
* see me afterwards if you don’t know any jokes about
naming things being hard
19. Naming smells
19@PeterHilton •
foo, data, object
employee, employee2
acc, pos, a, i, T, U
>=>, <*>, ¶
InvoiceManager, getPrice
isOpen, dateCreated
appointment_list, company_person
shipment, order, journey
1. Meaningless and abstract names
2. Numeric suffixes
3. Abbreviated or short names
4. Symbolic names
5. Vague words
6. Vestigial Hungarian notation
7. Multiple words
8. Wrong names
20. Adopting better naming practices
Recognise and fix naming smells
Start with meaning and intention
Use words with precise meanings
Prefer fewer words in names
Never use abbreviations in names, except for id
20@PeterHilton •
21. How to name things
(the hardest problem in programming)
1. Learn to recognise bad naming
2. Refactor - rename bad names to better names
3. Improve your vocabulary by reading and gaming
4. Wield your thesaurus and dictionary
5. Adopt better naming practices
6. Learn to write
7. Tell jokes, especially puns - learn to spot ambiguity
21@PeterHilton •
22. 3. Write clean code
4. Get better at naming
22@PeterHilton •
23. Explanatory functional tests
Acceptance Test-Driven Development (ATDD)
Behaviour-Driven Development (BDD)
Specification by Example
… use acceptance tests written in domain language,
in collaboration with requirements stakeholders, that
document system behaviour (in addition to unit tests)
23@PeterHilton •
24. @PeterHilton • 24
‘Like cheap wine, long paper
documentation ages rapidly
and leaves you with a bad
headache if you try to use it
a year after it was created.
On the other hand,
maintaining a system
without any documentation
also causes headaches.’
27. Clean code and good
unit tests are great,
but they’re not enough
(this is the bad news)
27@PeterHilton •
28. Clean code & tests are not enough
Even if you could write clean code all the time (you can’t)
your code still needs more explanation.
You don’t have to repeat yourself to the compiler, but
human learning requires repetition.
You have to repeat yourself to help people understand you.
However, Uncle Bob is misleading about comments…
28@PeterHilton •
29. Comments are the
easiest way to document
code. If you don’t have
comments, you probably
have no docs at all. 29@PeterHilton •
30. Write good comments
1. Try to write good code first
2. Try to write a one-sentence comment
3. Refactor the code (make it easier to explain)
4. Delete unnecessary comments
5. Rewrite bad comments
(all good writing requires rewriting)
6. Add detail where needed
(which isn’t often) 30@PeterHilton •
31. ‘Beware of DRY, the
evil siren that tricks
you into abstraction’
Martin Thompson a.k.a. @mjpt777
31@PeterHilton •
33. Too much abstraction
Dogmatic adherence to do-not-repeat-yourself leads to too
many abstractions.
Most of these abstraction layers don’t correspond to the
domain, so you can’t find good names for them.
(Half probably aren’t abstractions anyway, just indirection)
33@PeterHilton •
34. The Rule of Three
‘The first time you do something, you just do it.
The second time you do something similar, you wince at the
duplication, but you do the duplicate thing anyway.
The third time you do something similar, you refactor.’
- Kevlin Henney
https://vimeo.com/138863968
34@PeterHilton •
38. There’s not much
point writing
maintainable code
if you don’t actually
maintain it 38@PeterHilton •
39. Proportion of clean code during software development%cleancode
0
25
50
75
100
number of lines of code
April Untitled 3 Untitled 10 June Untitled 5 Untitled 8 Untitled 11
‘We’ll clean it up later’
‘There’s too much
code to clean it up’
40. Clean code
All of your code can be clean code, in theory…
But this gets harder as the codebase grows
Code falls off the maintenance cliff after around 100K lines
This is more likely to happen with business applications
than focused libraries for developers
(Likely the strongest argument for external dependencies)
40@PeterHilton •
43. Constantly improve the code
Take the Boy Scout Principle seriously (actually enforce it)
Do code review on all changes
Recognise code smells
Refactor
Even if you can’t win, you can lose more slowly
43@PeterHilton •
44. 8. Keep the codebase
small
9. Increase refactoring
effort as it grows
44@PeterHilton •
45. README-Driven Development
45@PeterHilton •
‘… we have projects with short, badly written, or entirely
missing documentation…
There must be some middle ground between reams of
technical specifications and no specifications at all. And in
fact there is.
That middle ground is the humble Readme.’
http://tom.preston-werner.com/2010/08/23/readme-driven-development.html
46. Write a project/project introduction
Explain the system’s purpose
(What is the business reason? Why are we here?)
Describe the scope
(What defines what the system does and doesn’t do?)
Summarise what it does
(What does it actually do? What is it for?)
46@PeterHilton •
47. Detailed system documentation
Most systems don’t need detailed documentation.
Only complex systems require detailed documentation, e.g.
Architecture diagram
UML diagram
Data dictionary
Process model
Business rules 47@PeterHilton •
50. ‘Hell is other people’s
code’*
* Sartre didn’t actually say this
50@PeterHilton •
51. Summary
51@PeterHilton •
1. Recognise unmaintainable code (and refactor)
2. Write clean code (and get better at naming)
3. Write acceptance tests that explain functionality
4. Apply The Rule of Three before you remove duplication
5. Accept that maintainable code costs more
6. Write docs and comments for the code you actually have
7. Keep the codebase small (or increase refactoring effort)
8. Write the minimum viable system documentation