Reading code vs. writing code
In a legacy system, what is it that you spend absolutely most time on?
I would say, understanding code and finding out where to do a change. Most of us have been in the situation that we spend hours or days looking for exactly one single line that would be changed in a million line code base. And of course trying to figure out what effects that little change would get. Expected and unexpected.
In an old Cobol system I came across, even the most experienced developers often spent two weeks analysing what consequences a change would get. Of course that was before the time of unit tests and modularisation of code into microservices, but the correlation of the time it took to write code compared to change it was very obvious.
What are we looking for in a code base?
Let’s say I’ve got at task at my new job. I’ve got requirements that needs a change in the code. I have to find the exact lines to change. Being in this situation, I’m often confused. I can’t immediately see the overall structure and don’t know where to look for the code I’m about to change. I try to figure out certain things, for example:
Where is the code..
- ..providing the UI or API?
- ..that call the infrastructure like database or file system?
- ..handling integrations with other systems or services?
- ..handling the business logic?
- ..defining configuration?
Also, I’m looking for the code that handles the business domain that I want do my changes in? In a monolith there might not be any separations by domains. In a microservice architecture there might be a better separation. For example, managing hotels is handled in the Hotel Management Service. Price changes are handled in the Pricing Service. And so on. Preferably I would like some form of graphical overview that could map the business to the system.
The house metaphor
When talking about this, my and my teammates often use the house metaphor. Many of us have owned or lived in a house, we know how they usually are structured and we get help from craftsmen to do maintenance and changes on our houses. There is a lot of similarities with a system.
A house is divided into separate rooms. Each room has a purpose; cooking, sleeping, storage, bathing and so on. Each room is optimised for the users’ (people who live there) needs.
Craftsmen come to the house with a mission to improve something or fix stuff that has broke. Depending on what they’re going to fix, they go to different rooms. They immediately know which room they are looking for. If they are about to install a new shower, they will go to the bathroom, if they are fixing the dishwasher machine they go to the kitchen. Nobody would look for a shower in the bedroom. There might of course occasionally be exceptions, I heard about someone having a TV built in to the bathroom floor.
If there isn’t a map, they will make a quick glance in each room to find out what type of rooms it is or ask the owner. Within a few minutes they grasp the location of everything in the house.
Before looking for the appropriate room, the craftsmen must of course find the correct house. In a city of millions of houses. First they might ask which district the house belongs to, and after that which address.
Here the craftsmen has an advantage compared to developers. We rarely get the “address” of the service we’re going to change together with the requirements. Sometimes we can start out in the UI and follow the code to find out in which are the changes should be done, and sometimes we simply have to ask someone in our team. Preferably, we always go through the changes with someone that is experienced within the system before we start to find out where to make the change.
What can we learn from managing houses?
If we could significantly decrease the time a developer spend on trying to find out what the system does, there would be a huge benefit for companies. Time could be spent on new features, and more features. So how do we do that?
- Define what it is you’re building. Is it a storehouse, a bungalow or a skyscraper? Sometimes you start with a bungalow and end up with a skyscraper, it’s pretty obvious that the architecture is not clear and easy to follow in that case. When this happens, refactoring is crucial to build a maintainable system.
- Define responsibilities. Define responsibilities of services (e.g. hotel management), layers (e.g. domain layer) and classes (e.g. controller, repository). Then developers immediately will understand where to look for the code they want to change. Is the change about the contract between the client and the API, then look in the controller classes in the API layer. Is it about the communication to the database, then look in the repository classes. The shower should be in the bathroom!
- Use commonly used patterns and guidelines. Most houses have a similar set of rooms, with similar purpose. This makes it easy for us to quickly understand the usage of each room. I your system follows a well-known way of structure the code, it will be easier for new users to start working with it.
And one more thing. Draw a picture of the system and make sure that the system’s file structure represents that picture. If there is a box named Hotel Management on the picture, make a folder named Hotel Management. If there is a layer named domain layer, make sure the developers can find a folder with that name in the code.
I think most developers find the above ideas pretty obvious. Despite that, many systems end up with an unclear structure. There are many reasons for that; tight time schedules, bad communication in the team, problems in combining helicopter perspective with frog perspective.
Systems often live up to 20 years and during that time a certain amount of developers are passing through. All of them with different experiences from previous systems they have worked with. If they could be up and running quickly, if they know what they are doing when making a change and if they easily can find a specific place in the code then time to delivery will be shortened and the quality improved. The changes will be more aligned with existing code and cause less confusion for other developers. The risk of causing bugs with the change will be lowered.
Companies will have everything to win, and nothing to lose, on encouraging the development team to keep a good code structure!
Same theme, another metaphor: https://medium.com/nick-tune-tech-strategy-blog/the-chocolate-sauce-design-heuristic-3cdc143dd2ea