Now that it’s time to move beyond analysis, it’s time to start refactoring your monolithic app’s models, right?
Er, not quite.
The models are a great place to start your analysis, but should be just about the last thing to refactor.
If you’ve ever seen This Old House[0] you know that in a major home renovation you do the structural work first, then the supporting work, and finishing work like painting last.
However helpful the analogy is between a software project and an old home renovation, there are some distinct differences between an old home and a computer program (Django or otherwise).
The key difference we want to start with is based on the presumption that your Django project is an active production application and you want to keep it up and delivering value even while you make changes.
There’s no spending a few nights with family or using a laundromat while an updated laundry area is carved into the 18th century fruit cellar.
So your changes need to make as little disruption as possible.
I’m going to make a big assumption here and assume that in the analysis of your monolith, and related apps, you saw a few potential apps and modules into which to move components. After all, if you didn’t already have this plan then you’d be getting ready to move code around quite willy-nilly.
More often than not you’ll end up with at least one module that seems to provide supporting code of some kind. This could be strict utility code (general base classes, helpful functions, test infrastructure) or something of a business logic nature (account and subscription tracking are common in SaaS projects!).
This code is at the top of your hierarchy of dependence.
And this is the code you pull out first.
It may be in the form of another Django app (or apps) or Django-free Python modules (which comes with its own advantages). Pulling out common code first reduces the remaining “code surface area” and also risks, whether bugs or merely cognitive drag, of treating sibling apps as core libraries.
Now comes the time to spread apart your monolith into _horizontal _components.
This type of separation is usually organized around recognizably different business functions. And there may be some degree of hierarchy here, but not to the degree of utility library.
For example, if you have an app with locations and reviews all in one, it will [likely!] make sense to break out the locations and reviews into their own respective apps. This is true even if there’s a database/foreign key relationship from one to the other.
Keeping in mind that we want to break apart the monolith in such a way that everything still works, the key is to start with small components. This is not without its own risks, as during the course of this work you’ll be left with an app or apps that are partially in one app and partially in another. You can either live with this or do everything in one fell swoop, which for most production apps isn’t a great choice.
The first things to move are the easiest things to move. This will vary from project to project, but one suggestion is to start with the URLs, and then proceed to views, forms, template tags, templates.
Like I said, this could look a little weird, but the benefit is that the URLs provide a structure for an HTTP application and this gives you a home to start moving code.
Yes, you will have a urls file referencing views in a different module for a little while, and then your views will reference forms and templates in a different module, but this gives you traction and in this kind of project traction is worth a lot.
What about tests?
Move those when you move the code they test!
Next week we’ll discuss the elephant in the monolith - moving your models.
Reverse relationally yours,
Ben
P.s. I started work on a book a while back, a guide to writing Django Standalone Apps. It’s been hard to wrap up so I thought maybe I’d leak it bit by bit over email instead of trying to finish it in one go. Is that something you’d be interested in? If you’d be interested in getting a drip-campaign version of the Django Standalone Apps book just click this trigger link and I’ll start keeping a tab of interest :)
[0] Never heard of This Old House? https://en.wikipedia.org/wiki/This_Old_House and here’s a great old episode on YouTube - notice in the first few minutes how Norm discusses assumptions about the support for the second floor based on the support for the first floor, and of course the understanding that this is an assumption that will be tested by actually doing work on the structure.
Learn from more articles like this how to make the most out of your existing Django site.