- Published on
Clean Code: Keeping Everything Seiso
- Authors
- Name
- Asfiolitha Wilmarani
- Trakteer
To be completely honest, cleaning is not my most favorite thing in the world. In this article, I’m going do discuss about why we should write clean code so we wouldn’t have to clean up after ourselves later.
The Gravity of Bad Codes
So. Here’s the thing. Bad codes are easier to write than their cleaner counterparts–and that’s precisely why developer gravitate to it.
There are at least a million excuses as to why developers write bad codes1.
- It takes less time to write
- I just want to get it over with so I can code something more interesting
- I don’t feel like cleaning up right now, I’ll clean up someday
- A working mess is better than nothing, innit?
source: dev.to
As mess build up, it’s harder to make more change and build on top of a muddy spaghetti. By harder I mean it takes a lot more time and effort (i.e. manual labor). This results in decreased productivity, which drives management to add more resources to work on the mess, may or may not make things even worse.
Remember how I said one of the excuse of writing bad codes is that it takes less time to write? Essentially, you’re meeting the deadlines by making a mess. But once the mess is made, you will ultimately start to slow down. Hence why, in order to keep meeting deadlines, you gotta keep the code clean ASAP.
What is Clean Code?
Essentially, clean code is a code that’s easy to deal with. It’s supposed to be easy to read and easy to change. It doesn’t tempt the reader to modify it which will make the code worse.
A clean code is also focused, straight-forward, and doesn’t allow bugs to creep by the corners. It doesn’t do one thing repeatedly. It also shows that the developer who wrote it actually cared about the code, the reader, and future maintainer of said code1.
Clean Code in Practice
A lot of articles cover the supposed programming bible, “Clean Code” by Robert C. Martin. I found a very handy summary that lists all the important rules2. I’ll also list some of them here~
General rules
- Follow standard conventions.
- Keep it simple stupid. Simpler is always better. Reduce complexity as much as possible.
- Boy scout rule. Leave the campground cleaner than you found it.
- Always find root cause. Always look for the root cause of a problem.
Other than the four mentioned above, these are more principles to code by.
- Ya Ain’t Gonna Need It (YAGNI) — this is when you add a piece of code thinking it will be useful for some distant future feature. You know what? It will probably never be implemented in the end anyway, remove that code.
- Don’t Repeat Yourself (DRY) — as it says, it’s when your code does one thing over and over. In our case with React Native, we take care not to make duplicate components that essentially do the same thing and try our best to reuse existing components.
- SOLID — this one actually stands for several programming principles, namely: single responsibility principle, open-closed principle, liskov substitution principle, interface segregation principle, and dependency inversion principle.
Naming rules
- Choose descriptive and unambiguous names.
- Make meaningful distinction.
- Use pronounceable names.
- Use searchable names.
- Replace magic numbers with named constants.
- Avoid encodings. Don't append prefixes or type information.
We use PascalCase for naming our components, and this is uniformed throughout the entire project.
For navigations, we used named constants in a separate file as well.
export default {
INIT: "Init",
LOGIN: "Login",
REGISTER_MNEMONIC: "RegisterMnemonic",
REGISTER_PASSWORD: "RegisterPassword",
REGISTER_CONFIRMATION: "RegisterConfirmation",
HOME: "Home",
QR: "QR",
ONBOARDING: "Onboarding",
COIN_DETAILS: "CoinDetails",
};
Functions rules
- Small.
- Do one thing.
- Use descriptive names.
- Prefer fewer arguments.
- Have no side effects.
- Don't use flag arguments. Split method into several independent methods that can be called from the client without the flag.
Here’s a very small yet essential utility function we used to format the currency displayed on our app. At first, we struggled on deciding how many floating point to display, because some tokens are worth less than one cent and it would display as zero if we used regular currency formating. Therefore, we decided to use regex to parse the number given by our API of choice to separate the thousands with commas and six-digit precision.
export const currencyFormat = (num: number) => {
return `$${num.toPrecision(6).replace(/\d(?=(\d{3})+\.)/g, "$&,")}`;
};
This gives us separation on the tokens that are worth thousands of USD (such as bitcoin at the point of writing this post) and enough precision to display (almost) the full price of tokens with prices less than one cent.
Tests
- One assert per test.
- Readable.
- Fast.
- Independent.
- Repeatable.
Writing tests with jest really couldn’t be more readable. Here’s one of the test I wrote for the watchlist feature. It can literally be read as “WatchlistButton should add token to watchlist if not exist”. The syntax is cooked to perfection. I also only need one assertion here. In this case, the keyword is expect
instead of assert
.
describe("WatchlistButton", () => {
...
it("should add token to watchlist if not exist", async () => {
const { getByTestId } = await setUp();
const watchlistButtonInstance = getByTestId("watchlist-btn");
fireEvent.press(watchlistButtonInstance);
expect(useWatchlist.getState().watchlist).toStrictEqual(["USDT"]);
});
...
});
Moral of The Story
Once in one of my internship experience, I had to work with a code my senior left for me. I was tasked to build another feature on top of said component, but let me tell you, that thing is Ugly. In italic with a capital U.
That task was such a big headache and I swear I wouldn’t want to do any refactoring of another dev’s work ever again.
Anyway, fortunately the project we’re currently working on in El Pepe doesn’t really let dev’s work overlap with each other too much. Fortunately as well, all my team members are great programmers who write decently reable codes~ What a blessing.
In any case, it really costs everyone a tremendous amount of energy to work with ugly code. That’s why I try my best to write as little code as possible to implement a working component. At least, on the functional side. (I can’t really say the same for styling–I never fail to go crazy on styling.)
TL;DR
Clean code good. Messy spaghetti bad. Keep it seiso.
That’s it for this. See you on the next one~