Engineering road for me was a bit denser than it usually is, mostly because I've chosen to go Remote from the start. I'm grateful for that decision to this day!
I had a pleasure to wear many different hats thus far (Fullstack, Backend & Chaos Manager). Each was enjoyable in its own way, but I've learned the most from those moments which got me to the edge of my nerves.
Following is the list of practices I consider of the utmost importance for a Software Engineer, which was curated mostly by those down-times of my career.
Suffice it to say, I consider this point to be the worst of them all. Duplication should be absolutely forbidden. There are a few types of duplication, but essentially they all originate from the code.
It's easy to imagine a situation where our Bob the coder copies existing logic with minor changes to the functionality (or even worse, no changes at all). At that point, two duplications have happened - of code and of knowledge. The later is a bigger issue. Even Bob will forget after some time what crime he did and where it was committed - so knowledge base will have a leaking hole in it, and it will be written to technical debt.
In 99 out of 100 cases, duplication of code could & should be avoided. It's better to invest some time into adequately designing an abstraction for better reusability, then to accept mediocre code.
To avoid it, the easiest way is to have a top-down decision about it. Enforce code style rules. And have an analysis tool to provide feedback to developers in case some duplication happened. While you are at it, you could also read Clean Code by Uncle Bob - he covered the subject better than anyone else.
Even my granny knows about TDD at this point. Or so I thought? Almost every single company that I had a pleasure to work with didn't implement or enforce TDD. And those where testing existed, it was to a minor degree.
It is up to us, Engineers, to request from the management of a company to have some understanding, and give us a breading room in the beginning.
First, let's agree on what TDD is:
TDD enables us to create modular, well-designed code, without doing any upfront design. Starting with a test first forces you to think about the intended behavior. Need to refactor then forces you to think whether your solution fits in the bigger picture, or not. And as a side effect, you end up with a codebase that has at least decent test coverage.
Now that we are in an agreement, I have a statement for you:
Let me clarify. Speaking from personal experience, in the first two months or so it took me on average 40% more time for TDD. But as I progressed, naturally it only got so much faster. At this moment IMHO it takes me maybe even less than 10% of complete implementation time, and a side effect of this all is that I only got faster overall. That's probably due to the fact that when you use the TDD approach, you actually have to think about the implementation you wish to achieve.
One more side effect is that you don't have to be scared about making some changes to the part of the code you don't know anything about. If your colleagues follow similar principles as you do, then you can rely on the stability of the codebase, or at least be fairly certain that bigger issues will be avoided.
TDD eradicates the fear of change.
Once tests are run, in case of failure we want to see a verbose output, which will save time and energy in reproducing the failure onwards.
Good unit test failure report consists of the following:
Strive for each test to answer all these questions. Avoid complexities! If you are mocking something, then you didn't do your job right - at least engineering part of it.
This is something that you could have already guess is coming. That statement is primarily targeting unnecessary coding activities.
Let's say you got a request for the feature. Don't implement it straight away (no matter how much your manager is pressuring you). Find some time to solve it on paper, speaking in an abstract manner. If you manage to do so, then translate it in as little code lines as possible. You can later justify the time used by time saved on readability and future maintenance.
If you have an idea about the improvement of a codebase - make a note on it and discuss it with the rest of the team if you should implement it.
Plan for the future, but do for the present.
Performance is good, but don't overkill it. Try to look at it objectively - is it really needed to go that extra mile? And if so, have evidence to back it up, because someone will definitely ask where did that extra time go to.
Automate as much as possible. You don't have to be DevOps ninja to make your life more enjoyable.
If you have a process that happened twice, write a tool for it - either a full-fledged CLI or a simple BASH script. You'll enjoy next time that same process arises, and you are prepped to go to war.
Start using bash Aliases, it's not so much about saving time, but about the effectiveness and inner hacker feeling. :bug:
If you don't already have a Continuous Integration pipeline, build one as soon as possible. Aside from the point that you'll have an almost identical environment as production will be, ease of development is the bigger reason. You simply won't have to think about your local setup (or if there are any differences between your environment and that of your colleagues). docker-compose should be your best friend. Even better, write a script to abstract it. ✊
Have any comments or suggestions? What would you like to read about next? Drop the comment down below and let me know
Leave your email if you wish to get notified each time I post an article