Ask HN: What's your best clean code tip?
18 comments
Disclaimer: Like every heuristic, this is context-dependent and doesn't fit every situation.
That being said, I find it helpful for top-level scripts to be "about a page long" at most
e.g. often a 300 line main.py file is overkill and becomes easier to understand if compartmentalized down to a few high level components like connect(...), load(...), parse(...), etc
That being said, I find it helpful for top-level scripts to be "about a page long" at most
e.g. often a 300 line main.py file is overkill and becomes easier to understand if compartmentalized down to a few high level components like connect(...), load(...), parse(...), etc
Focus on naming accuracy. Clear thinking is often apparent in how variables and methods are named.
Assuming imperative/object-oriented code: organize classes/structures around mutability patterns, and don't mix badly. Favor side-effect-free functions and immutability without getting dogmatic, and be clear about member/struct variables that are mutable accumulators, registers, etc.
Build abstractions at the right time. Base classes and common structs should hold completely common information, not be a bag of data that may or may not be there. Be tight with your reasoning about inheritance.
Write tests, useful ones that exercise the logic. (Setters and getters aren't worth it usually.)
Build abstractions at the right time. Base classes and common structs should hold completely common information, not be a bag of data that may or may not be there. Be tight with your reasoning about inheritance.
Write tests, useful ones that exercise the logic. (Setters and getters aren't worth it usually.)
Favor simplicity. Build abstractions at the right time, not all the time.
Run it through a pretty printer?
Try for no warnings with your static code analyzer / linter / compiler?
Make tests for it
Add logging
Put it on gitlab pipeline, make a CI/CD for it
Make it as a standalone docker container (see above point)
Update or make the readme.md
Try for no warnings with your static code analyzer / linter / compiler?
Make tests for it
Add logging
Put it on gitlab pipeline, make a CI/CD for it
Make it as a standalone docker container (see above point)
Update or make the readme.md
I second tackling all analyzer/linter/compiler warnings, but add them to CI and do the test coverage first.
This will allow you to surface metrics (for advocating the cause to management) and make cleaning up the code an ongoing task for technical-debt sprints.
This will allow you to surface metrics (for advocating the cause to management) and make cleaning up the code an ongoing task for technical-debt sprints.
KISS (keep it simple stupid), read lots of other people's code and see if you can understand it and if not what would you change? Adam Savage frequently mentions a trick for makers that I think applies here: What would the future you think about that code? Would they feel nice having something extensible and not too complicated or be upset that the code works but is a mess to extend and fix?
Clean code always suffers when new feature comes in.
So don't be lazy and try to put that new functionality into a new class instead of trying to squeeze it into existing classes and functions - that makes it more testable, separated and uses the "composition instead of inheritance" dogma. It will make the code somewhat cleaner and a thousand time more refactorable.
So don't be lazy and try to put that new functionality into a new class instead of trying to squeeze it into existing classes and functions - that makes it more testable, separated and uses the "composition instead of inheritance" dogma. It will make the code somewhat cleaner and a thousand time more refactorable.
KISS: keep it simple, stupid.
If the method/function doesn't fit on my screen it's too long.
Learn to comment effectively.
I like to sort CSS properties alphabetically.
#header { background: grey; color: white; display: block; font-size: 12px; }
#header { background: grey; color: white; display: block; font-size: 12px; }
A tool should be able to do that.
My tip: divide the problem in small pieces.
Rewrite it from scratch a couple of times.
If you can reduce the number of lines of code — you must reduce it.
This is terrible advice to follow blindly. We would all end up with metaprogrammed everything that makes understanding, navigating, and diagnosing code unnecessarily difficult. It also doesn't distinguish between factoring along seams that are stable (domain concepts) vs implementation details which leads to a brittle codebase.
2. Don't be eager to concretize your abstractions. e.g. It may be the case that you need to use a state machine (SM). If you already have state types/objects, you can add what's necessary to clearly document and enforce transitions. What isn't always necessary is extracting the state machine portion to an abstract set of nodes/edges. Such a thing is useful if you have either dynamic SMs or multiple similar ones that are hard to maintain 'in place'. You can easily tell which path you're on if your class names don't have any domain terms in them and instead layer mechanism names. i.e. A class/object can implement a mechanism without having it extracted to being its own class/object.
The above could be summarized to saying write "clear code" (domain level thinking) rather than the shallower "clean code" mechanical refactoring.