The Messy Edition
The power of bounded contexts, making a mess and why Active Record is an anti-pattern.
Another week, another edition of Practical Software Design.
Here’s what we’re covering:
The power of bounded contexts
Making a mess
Active Record is an Anti-Pattern
It’s going to be a controversial one this week. Let’s get into it!
The Power Of Bounded Contexts
Small Rails apps are easy to manage.
But as the codebase grows, I've run into some big problems:
God objects - large classes that hide huge numbers of methods
Duplication of ideas - similar but different concepts across the codebase
Conflicts - teams stepping on each other's toes
An idea from DDD can help here - bounded contexts.
A bounded context is a self-contained area of the codebase that has it's language.
Example: An app to run a garage might have bounded contexts for sales, marketing, servicing, and accounting.
Each of these contexts will have a concept of a "customer", but it's a different model depending on the context.
Ideally, data should be separate too, but that's tricky in Rails, so in the past, I've shared one database table for all customers.
However, you can have a Sales -> Customer, a Marketing -> Customer etc as Rails models under namespaces.
Once this has been done, you can put sales behaviour in one customer model and marketing behaviour in another.
Bounded contexts are fantastic for breaking down a large monolith.
I'd love to hear other people's experiences. Reply to this email!
Make a Mess
Stop refactoring.
Instead... make a mess.
When I first heard this from my mentor I did a triple take.
"But... surely we want clean code ASAP?"
No. And here's why.
There's a temptation amongst developers like myself who love refactoring to use it whenever they get a chance.
The first chunk of code that's more than three lines... and BLAM!
We extract into a method.
The first bad name we see... and BLAM!
That sucker's been renamed throughout the whole class.
But there's a big problem with this approach.
You can be too DRY.
When you refactor too soon, you've not let enough of a pattern emerge.
As Sandi Metz says "Prefer duplication over the wrong abstraction".
Wait. Wait for that mess to build up.
Wait until it's almost intolerable.
At that point, a pattern will emerge and that pattern will tell you the right abstraction.
Then, BLAM you've refactored, not just for the sake of it, but because the code is telling you to do that very thing.
Controversial? Maybe. Let me know what you think…
Active Record is an Anti-Pattern
Active Record is damaging your codebase.
Repositories are one answer.
Why do I say this?
I've been in a lot of Rails codebases in the past few years.
Many folk think that going against Rails is futile.
"The Rails Way Or Nothing" they cry.
"Let's Try A Different Way" say I.
Rails is brilliant for getting a project off the ground.
Once it grows to a certain size, the Rails Way hinders you.
Rails uses a pattern called Active Record.
It encourages stuffing business logic and persistence into the same class, along with many other unrelated concerns.
One alternative is the repository pattern.
I've introduced repositories in Rails codebases recently.
It's still early days but here are the benefits I'm getting:
* Swappability - we can swap out the database for in memory repos in tests, leading to better design and flexibility (as well as some speed)
* Isolation - we can access APIs via repositories, leading to our code being less coupled to external vendors
* Less mocking - because we're now not coupled to APIs such as Stripe, we don't need complicated mocks in tests
What about you? Have you used repositories before?
Found them helpful? Annoying?
Either way please let me know in the comments or just reply...
Want Some Help?
I have two options:
Book a 1 hour coaching session (normally $200, FREE for a limited time)
Have a great week!