Some days ago, someone in my company asked me a fair-but-not-easy-to-answer question:
How do you think I can become a good software developer ?
Without much time to prepare to this question my first answer was about trying to build a real project. You can read and follow a lot of tutorials (of course they are important) but you will not really learn until you put them into practise in a real project.
If your company does not use a given technology you want to learn, just start your own project using it. It does not need to be successful in terms of business, but needs to be real.
After this quick answer, I started to think on when I started to feel like I was becoming a mature software developer. This is the outcome of my thoughts:
Understand that the code you write is for others to be read
This is something very basic, but sometimes we forget. The code we are writing today, will be read and maintained by others or by ourselves in the future. Also the effort a company (or a group of developers) takes for developing an application is very small compared to the effort they will invest in maintaining it (solving issues, adding features, improving some areas, etc.).
Some basic rules for accomplishing this are:
- Do not relay on comments to explain the code. Code needs to be self explanatory, so by reading the code everyone needs to understand WHAT is being done. Comments should be used only when the WHY of what we are doing is not clear, or to explain lines of code that might look like potential bugs to others.
- We all like to write perfect algorithms and super-optimal code, but it usually makes code difficult to read. Do not write too much magic in your code, and if you need it, enclose it in methods with a clear naming.
- Perform code reviews frequently (during every push for example). The reviewer should understand the code without many explanations from the developer that wrote the code, so make sure that variables and method names are clear.
- Use an external tool for validating the code style. There are plenty of them, and they ensure that the code is uniform throughout the project.
Decide clear naming for methods and classes
This is related to the previous aspect, but it has special importance. If you think of how to name a method or a class you are deciding its responsibility and its boundaries, so it will help to design a modular system.
The name of the class, method etc. need to make clear to everyone what it holds. For this to be true, we need to ensure that the contents of the class or the behaviour of the method, its inputs and its outputs match the name you choose. If they not, or if they change overtime, no not be afraid of changing the name to be accurate.
Examples of bad names include the typical *Helper. This name states who is helping to, but it does not helps to understand what this class holds. For example StringHelper can hold validation methods, formatting methods, constants, localisation, etc.
Learn about Unit Testing and keep it in mind when developing
When unit testing classes and methods, you need to think about the boundaries of those classes and the responsibilities and of method.
This includes what output needs to deliver to the caller, how to react to a given input and will arise lots of “what if” questions that will make the code very robust.
It will also help you thinking on the responsibilities this class needs to have and what responsibilities should be delegated to a different one, creating the dependency map in an evolutionary way and making the dependency injection something natural.
As you can see my main concerns about good developers are not about technical skills but about clarity in the code and structured projects.
If all this is accomplished a team can maintain the code easily, the can look for better algorithms for complex calculations areas in the code, or look for third party libraries that can fulfil some of the dependencies we might encounter.
Of course we can become experts on some technologies or some tactics, or infrastructures, but first we need to change or mindset and work for others. Not only for our customers, but also for other developers (providing easy-to-read code) and projects in our company (offering ways of reusing our code through libraries) or even 3rd party companies (by offering APIs).
What would you recommend so that junior developers can become good software engineers?