Sunday, March 04, 2012

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.
Given my context, I couldn't conclude that things should be broken up immediately, but I didn't want to ignore the point that Stefan was making about goals changing over time.

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.