When to Break Apart Your Application
At speakerconf Aruba 2012, Stefan Tilkov presented on the topic of building Systems. One aspect of his presentation that really struck a chord with me was around the competing desires while designing and delivering an application. This blog entry is about summarizing that aspect and what I took away from it.**
Stefan noted that early in an application's life, a monolithic application is far easier to deliver; however, as the application grows, what is important begins to change. The slide to the right shows how priorities can change over time.
While starting with a monolithic application is easier to deliver, that application often grows to an unmaintainable size - i.e. the vast majority of the time we boil the frog. Stefan argued that the benefits are so obviously there that for an application of any moderate size it's more efficient to bite the bullet and break things up (where logical) in the beginning.
I'm guessing the vast majority of the applications that Stefan and innoQ encounter probably began knowing that they would grow to significant size and would have benefited from any type of modularization, but my working environment is a bit different. When I start something new for a trader at DRW -
- the project may never grow to the unmaintainable size
- if it does, it's likely that I'll want things broken up in a way that I couldn't have anticipated when the project began.
Stefan also had a slide about Modularization (also on the right) that
gave numbers and recommendations on how to break things up. This slide
reminded me of Matt Deiters' presentation at speakerconf Rome 2011. Matt
told us about his experience teaching kids in Africa to program. While
teaching programming, Matt observed that giving the children the single
rule that they shouldn't have methods longer than 10 lines resulted in
the children writing code with SRP,
encapsulation, and other positive attributes. Matt argued that
beginning with a simple rule that could get you 80% of what you want is
likely better than 10 rules that, if followed correctly, could get you
100% of what you want.
I applied Matt's idea to Stefan's talk and suggested that perhaps the easiest thing was to take Stefan's modularization table and strictly adhere to changing things when LOC thresholds are broken. This would allow you to quickly deliver a monolithic application early in the development process, while avoiding boiling the frog in the future - once you cross the agreed upon magic number (LoC) then you aggressively address breaking the application into smaller and independent modules/processes/components/projects/whatever.
This strategy gives a nod to the fact that priorities do change as an application evolves and it's best to evolve the application along with those priorities, but not when it's too late. I plan to try this on my next greenfield application.
** I'm going from memory, so I could be slightly off. Don't hold Stefan accountable for my interpretation of his ideas.