This article describes my learning path as a software developer for the past 5 years. I recently started to put pieces together from my experience and some of my coworkers, and I thought it could maybe help other developers, so is the story of my climb through the summits of Software Development.
Summit one: Clean Code
Base camp: Code that works
I started working as a professional developer 5 years ago. There were not any kind of development classes at my school, so I mostly learned how to program in my free time and at work.
At first, I was very excited about software development. I would learn new things every month. Over my first two years I would learn Angular, then Symfony, then Vue, then Django, then React and React Native.
After a while, I realised the code I was writing would just work® when I reloaded my application or server. I would no longer think "ok, let's save and see what is broken" 🎉
To me, being able to write code that works (most of the time) is the first peak I reached as I climbed through your career. But that summit is more of a base camp to the first real summit.
Clean code and getting no more feedback from code reviews
As I reached the "base camp of working code", I also found out I loved developing user interfaces, and I joined BAM to specialise in React Native.
I knew a lot of small tricks of React Native or redux-saga to achieve in a simple way some complex user stories.
Most importantly, I was getting close to zero feedback on my code reviews. That was mostly because of experience. I knew how to name my variables in a way that made sense, and to discuss it with my coworkers when in doubt. I knew how to extract code in a long function or a big file. In short, even though I had not read the book, I knew how to write clean code.
I was at the top of the first summit, doing effectively what was expected of me as a developer. But if you've ever climbed a summit, you will know that you usually don't see any way up.
Getting stuck at summit one
Everything feels the same
Six months after reaching summit one, I felt I wasn't learning anything new in software development. Surely, I was learning a lot about project management and problem solving, but I thought my code from six months back looked very similar to my code at that moment.
Every time I tried to learn something new, I quickly gave up. I tried to get into a new language by learning purescript, I gave up after 3 hours. I tried to understand monads, I gave up after 30 minutes.
Those things sure looked shiny and cool, but I just did not see what use I could make of them, nor how it would help me in writing better code. To me, I was just learning to write clean code in purescript.
Every time I tried to learn something new, I felt I was climbing the same peak but on a different side, and that did not appeal to me very much.
There must be a place
Yet, I felt there was a way for me to learn more, even though I did not see how. This was particularly true when I tried to achieve big and complex features.
My approach was always to split the feature into smaller pieces, so that in the end I could solve every piece. But some people would come to me and recommend another way, usually using design patterns and object-oriented programming.
I always thought these solutions were adding too much complexity (everyone will have to learn the pattern! OOP is no longer the best way to do things!) and I could no longer approach my problem as a sum of small pieces, but they kept on insisting this would make my code simpler and more maintainable in the end.
I thought that maybe these people had climbed a summit that taught them how to climb differently, and now instead of making small moves they were able to get through obstacles making big jumps.
How to look above the clouds
Starting a long-term project
In July 2019, I was appointed software architect of a new big application that would require work over several years.
Up until that moment, I had either been working either on short-term projects (1-3 months) or on old legacy systems that were already difficult to evolve when I joined them.
I decided that my absolute goal was to never let this application become a legacy project, one on which it takes a day to add a button, or months to safely change business logic.
As I was looking for ways to write more maintainable code, I realised that a lot of people on Twitter were recommending TDD. I had practised it on few occasions before, but always on small parts of business logic. I thought it might be worth trying it a bit more often.
Base camp: TDD
So I started to practice 100% TDD, as a challenge to see if it would make my code better. After 1 or 2 weeks of struggling to find out how to test some of the lines of code I wrote (like React components), I became actually extremely comfortable with my test suite.
At that moment I felt the same excitement I had 2 years earlier when I started to write code that worked instantly for the first time. Instead this time, I was writing tests that were useful for the first time in my life!
That excitement was doubled when I realised I would only need to reload my app once for hours instead of minutes, and everything would just work every time!
But that was not even the best thing I got from TDD.
The moments I liked the most with TDD was when I did not know how to test the code I was about to write. I could not see any easy assertion to write, because I had to mock a lot of things or do a lot of setup before reaching the state that I wanted to test.
Every time that happened, I had found a way to change my design so that it would only take a small effort to write my assertion, and my design would end up a lot clearer and easier to change. 🥳
That is when I looked above and saw the second summit above the clouds: software design and architecture.
Summit two: Software Design and Architecture
Understanding what software architecture actually is
Don't get me wrong, I was appointed architect of this project so I was doing some architecture and some software design. But I had never been formally trained on it, I was doing it by replicating things I saw working on my previous projects (adapters, singletons, etc.).
I had no formal way of doing it, I would look at a feature and try to find the best way of implementing it. I had absolutely no scientific measure to indicate whether my implementation was good or not.
Now, when I realised this was something I wanted to learn, I started a book club on Clean Architecture at BAM. I learned a lot from this book and the discussions I had with my colleagues. If I have to sum them up, I would say 3 things:
1. The primary goal of software design is to make your code easier to evolve and change
2. Therefore, the best software design is the one that is easiest to evolve and change
3. A lot of people have already thought about this so there is a lot of knowledge available
That book club ended 4 months ago, and I have now been focusing on 3 things:
Architecting front-end applications
Teaching software design and architecture
Trying to find out at what the next summit is
Architecting React Native applications
A few weeks after the book club ended, I stumbled upon Khalil Stemmler's article Client-Side Architecture Basics. I found out that it was actually hard to apply clean architecture to a front-end project, and things are getting better and better every month, in large part thanks to him.
I have tried interesting ways of doing it, and that will probably be the subject for another article, if Khalil does not write it before me ;)
Speaking of which, another of his articles enlightened me and pushed me to write this one.
The next summit
In the How to Learn Software Design and Architecture - a Roadmap, Khalil Stemmler described the Map to Software Design and architecture. When I compare it to my summits, here is how it looks:
Base Camp: Code that works ⛺️
Summit 1 🏔 🥳
Design Principles (SOLID, DRY, etc.)
Architectural Principles (Policy vs. details, Coupling & Cohesion, etc.)
Architectural Styles (Layered, Monolith, etc.)
Summit 2 🏔 🥳🥳
Architectural Patterns (DDD, CQRS, etc.)
Enterprise Patterns (you'd better look at the article because I have no idea what these things mean)
You can see there is something after Summit 2, and I feel I am not there yet - don't get me wrong again, even though I have applied some parts of DDD and CQRS, I can't say I fully understand their benefits.
My prediction would be that at one point I would find out that my software design could have been better, had I made the right choices at the start. That will be the time for me to climb Summit 3, which I would probably call "system architecture" as it teaches you how to design not one feature, but how your features are organised.
Finally, if you'd like to react to this article, you can reach me on twitter @zawadzkil :)