Full talk: https://www.youtube.com/watch?v=QiaDztJZO5Q
Make a prioritised list of your current technical debt. Allocate time to tackle it and keep that list in mind when you are working on something new. Think about whether what you are writing will end up on that list.
Cohesion is where code does one thing really, really well. Code that is more cohesive changes less, and reduces effort to make any needed changes to it. One measure of cohesion is Cyclomatic complexity and services like www.sonarcloud.io can analyse this for you.
Tight coupling makes things hard to extend and hard to test, so try to remove coupling as much as possible. One example can be to allow a class to receive the data it needs to function, rather than have said class retrieve the data itself. See 9:15 in the video.
Don't program with desperation. Understand exactly what the code is trying to do, instead of trying random things in the hope that one of them works. Code should follow this list (given in order of priority, click for more info):
- Pass the tests
- Reveal intention
- Have no duplication
- Be simple
Ask yourself if you are the chosen one. If your problem is domain specific, go ahead and write the code. If you are doing something general, it has likely already been done — better than you ever could. You don't have to write every single piece of code yourself, instead make use of those who came before you. (Side note: Good code reads like a story, not like a puzzle)
Programs must be written for people to read, and only incidentally for machines to execute. - Abelson and Sussman
Don't always try to sacrifice readability to gain performance, because you might end up just killing both. Try to write code that reads well and works first, then optimise when you know there actually is a bottleneck.
These principles are taken from William Zinssers' book "On writing well: The classic guide to writing non-fiction".
Although the book is about writing non-fiction, it's principles can be directly related to writing code and documentation.
- Simplicity - Just like using large words in writing or speech doesn't necessarily make you any smarter, writing complex code doesn't make you a better programmer. If no one can understand your code, the code is useless.
- Clarity - Keep things clear for your audience. You aren't writing code for a 5 year old to read. You are writing code for another programmer to read. You don't need to tell them what
i++
does. - Brevity - Code should be only as long as it needs to be. Don't add fluff. Don't write methods that can already be done with the JDK.
- Humanity - Remember that at some point in time, another human will have to read your code, don't make it difficult for them. That human could be you.
Click here for William Zinssers' book, "On writing Well: The classic guide to writing non-fiction"
Your code should tell the reader what it does. Your comments should tell why it does this. Typically professors will demand comments everywhere, in reality it is not necessary. A common example for a useless comment is this:
i++; //increment
A door that needs a "push/pull" label is a bad door, it should be self documenting.
Single Level of Abstraction Principle
Ask two programmers what a long method is and you will not only get two opinions, but also a lot of questions regarding font size, screen density and god knows what. So as we can't agree on how long is too long, we can instead look at it as the number of levels of abstraction in the code. Instead of limiting the size, we should aim to reduce the number of levels of abstraction.
This goes back to the principle of a method doing one thing very well. As an example, a method doing form validation should not be making I/O calls. If you have methods that do multiple things, break them up.
Give all variables meaningful names. p
is not a descriptive or meaningful name, it could be anything. Try to avoid single letter variables, aside from the well known cases like i
for an iteration.
list.forEach(p -> p.getName());
people.forEach(person -> person.getName());
Review the test before reviewing the code.
Don't just report a bug, write a test that will fail because of the bug. This can increase test coverage and encourage people to write better tests.
Don't just write things for the sake of writing them. Do you really need that field? Do you really need getters/setters for that field?
By thinking about whether you really need a field before you add it, you can reduce the state, and state mutation.
Think more, type less.
No one can write the best possible code in the first sitting, so refactor it afterwards. Keep this in mind while doing so: Being able to accept your mistakes and to learn from them is key to getting it right next time.
Written up by: TobyLarone85 & I Al Istannen