Long story short - we took over an application with a monolithic architecture and with it we inherited a technical debt, carrying problems at every step of its development. This is a fairly common situation and a trite topic in the IT world, but I thought I'd write a few words about how we approached it, not having much experience with such projects.

A dozen-year-old project that still remembers WinForms and all versions of MVC, the outdated .NET Framework, Knockoutjs or the jQuery library. Intrigued? I invite you to read on, where I' ll take you, dear reader, on an adventure that you have been, are or will be a part of (if you have chosen this exciting path as a programmer, of course). To save your time, I will detail the points I want to discuss in more detail:

1. Brownfield project - or why, in my opinion, it's better to start with this type of project.

2. Achilles tendon in a legacy application. In fact, there will be several of them.

3. Incremental refactoring - that is, how to do a revolution in architecture, reducing the risk of failure.

1. Brownfield project. In the first point I would like to touch on one aspect that is often underestimated in this type of project - this is historical data. Unlike the much-desired and dreamed-of greenfield projects, here we have the advantage of having information on how users use our application. This gives us a great amount of knowledge that we can use in rebuilding and optimizing the processes in the system. The second advantage is that an application "warmed up" in production is a mature product that has been developed with the business for many years. Business knowledge, or business requirements are not always clear at the beginning of the development of an application or new functionality. Depending on the type of project, we need to take the right tactics. In our case, we had a good start because we had historical information that helped us get the application on the right track. For young teams, this is a great opportunity to learn the basics of programming and the art of collecting and processing data. Knowing specific use cases makes it easier to make architectural decisions. Maybe there will be another opportunity to write a few words about the second type of projects - greenfield projects and the Lean Startup approach.

2. Achilles tendon. Our application had a few unforgivable sins when it came to the broad engineering of good software and modern cloud native trends. One of them was the ubiquitous and omniscient session and cache. My advice? If you see an implemented session and API that communicates with the front-end and you can't do anything about it: Run! Half joking, half serious. Cache and session caused us a lot of problems and often led to the need for deep debugging. There are also pluses - we learned how to debug and got to know our environment - Rider - very well. How to get out of such a situation without locking ourselves in the basement for several years to rewrite the application? Our approach was to systematically persist "sessions" to the database. At the end of this section, I will advise you to invest in expanding your knowledge of Design-driven development, and in particular the topic of bounded contexts. Our legacy included two applications that, from a business point of view, had nothing or very little to do with each other. Such an abbreviation of two applications in a single soluition shows either laziness of developers, lack of competence or short deadlines. In summary - if you want to deliver quality software, you need time to do it.

3. Incremental refactoring. Personally, I am not a fan of rewriting applications from scratch. In our case it was impossible due to the fact that the application was in use and we had limited resources. On the other hand, I believe in agile programming, through which you can deliver something that brings value to the business in a relatively short time. We started by analyzing the system and calling the technical debt by name. We estimated that in a pessimistic case it would take us about a year to get this application out on track. As far as I was concerned - "no go". Inspired by the book Lean startup, we decided to MVP the most frequently used functions by users. In 3 months we gave away a SPA app written in React. Of course, we had to incur technical debt, which involved suboptimal queries (the N+1 problem), the use of an "anti-corruption layer" and some additional "work-arounds." Aware of the debt we had, we systematically paid it off in every possible iteration.

Our journey is not over yet, but we are consistently moving towards our goal. Briefly, but I hope I have inspired you, dear reader, not to lose motivation if you inherit an application that turns out to be a "Big ball of mud." How you approach this type of project will testify to your maturity as a programmer.

Piotr Czyż
@_piotr