A journey from unorganised to organised code.

A journey from unorganised to organised code.

Every developer's dream is to organise and provide a healthy structure in the repositories to make it easy and self-explanatory. Ironically, it is simple to say, but it is far more complex and requires immense wisdom to shape. Many times developers tend to organise so rigidly that they forget they step in an over-organisation arena.

Let's list some points to address the need for an organised code.

  1. To increase visibility within the code.
  2. Achieve a higher level of maintainability.
  3. Knowledge transfer becomes smoother.
  4. Readability is increased.
  5. Adding features becomes easier.

These are some common points above, I'm sure there are many more. The point isn't to list all of them but to express the intention hidden underneath.

How can we organise code better?

Before we dive deeper into this question, developers need to evaluate their current repository status. In a monolithic environment, everything gets pushed into a few key folders. Within those folders, an Onion Architecture emerges. Developers find it easier to push all controllers into a controller directory and so do repositories, events etc. I'm not saying these are good or bad practices. My point is, more towards point out that is it logical in the beginning to follow it when the domain isn't clear enough. Also, in my experience; developers are very sensitive to moving files around. They tend to keep pushing all events into one single events folder. This tendency is created by the need for delivery that undermines the need to consider possible structure tweaks needed as the system as a whole progresses. Every developer needs to question themselves; Is this the right structure if we keep adding files here? Or do we need a layer to identify features better?

Introducing the Monorepo.

Monorepo is a concept backed by successful companies. It helps to evaluate possible segregation strategies teams can adapt depending on the problem they are solving.

There are variations of Monorepo that manage packages, libraries, modules etc effectively. All in all, it is a good start to understand the Monorepo first and why ultra-large companies use them to organise their code. This gives us the foundation to talk about the topics listed below.

Discovering domains.

It isn't an easy task to discover a domain. According to Eric Evans, the definition of Domain is A sphere of knowledge, influence, or activity. If we combine this information with product-led growth then the domain must be an activity which dominates the outcome and influences success indication.

Well, the discovering domain requires an ample amount of efforts and wisdom to draw clear lines. If discovering a domain is something we are doing for the first time then it is worth watching Dr. Carola Lilienthal's video on YouTube about Domain Patterns – How the Domain Influences the Architecture It is a process that shapes gradually depending on the level of the mature product team reached. My recommendation is something to start by intuition and keeping flexibility in mind. I understand working with intuition will raise questions while thinking objectively. The point is, to at least initiate something instead of killing time by overthinking. Trust your guts. 😄

Using clear ubiquitous language within code.

Having a clear definition for the noun we use within a code is very essential. It is also important to document them as the domain is shaping. Recommendations of these nouns usually are borrowed by actively listening to customers, sales or product manager conversations on how they describe features. For example, salespeople may usually use the word "leads" to address users. Contrary, the Customer Success team will address users as "clients" or "customers". These minute use of words gives us a hint of how they perceive the tasks and activities they perform. These words also play a vital role in identifying bounded context.

Therefore, it is highly important to use proper nouns, verbs, plurality and tenses to denote the nature of the class and the feature it possesses.

Identifying bounded context.

As given in the example above addressing users as leads or customers also paves the way for identifying the bounded nature of a feature. While building an invoice feature, we can't address users as leads, and therefore avoiding using these words within the Invoicing domain can help us to promote clarity within the code.

Once the bounded context is identified, it becomes easier for us to structure our modules or sub-domains accordingly.

The mindset of experimenting and adapting.

Sometimes developers feel hesitant to change namespace naming and adapt to the change the product manager requested. This occurs when code is tightly coupled and room for refactoring is less. The questions on quality test cases also appear and many times developers undermine the need to have TDD as an approach to write code. All these factors contribute to long-term unorganised code which hinders maintainability.

To counter this issue, it becomes a need for the tech team to start identifying quality testcases required to provide agility within organising. Experimenting in finding optimum solution also gets neglected because the fear of breaking things overwhelm. In these cases, the team can start small and start putting foundation work needed. Then gradually add quality testcases and adapt accordingly. Once we accomplish a certain level of assurity with the tests, regardless the test was only written for a very short portion of the application; it is still fine. It is a good start and every progress is good progress.

Regarding, what are quality testcases? Then it will require an independent article to address this explanation. In short, quality testcases aren't about achieving 100% coverage. Instead, it is about how many critical business scenarios we have already dealt with.

Encouraging autonomy in the teams. From writing codes to writing stories.

Stories within the code describe the eloquence of the author. It showcases the depth of understanding a developer possesses and highlights the art of programming. When a developer can express stories within the code then they have achieved a level of mastery in programming. It doesn't matter how many design patterns we know by memory. All that matters is how we use them and why we use them in places. Knowing all design patterns shouldn't be an objective for the developers but being able to identify places where there is potential for a design pattern to be Google.

Now what exactly do I mean by "stories" and how it play a role in programming? Stories are a collection of features structured in a way that they are efficient, easy to navigate and set pragmatic examples of KISS and DRY principles. It is an art of expression and craftsmanship.

SOLID survive in all weathers.

SOLID principles can be seen as a security guard over contributing code. If a developer understands SOLID at its finest then he easily knows how to structure and limit the classes. This becomes a building block and as time passes refactoring them becomes an easy task. Please make sure to still have critical testcases in place and adapt TDD as a whole.

I may have used many abbreviations and many tutorials can help to explain them in detail. The point of this article was to provide enough information but at the same time be minimal and up to the point.

Subscribe for daily recipes. No spam, just food.