This message was imported from the Ruby/Rails Modularity Slack server. Find more info in the import thread.
Message originally sent by slack user U782WI24OVK
I’ve got another question for you folks.
Say you’ve end up with a big ball of mud and you’re about to start splitting into components. I think generally you’d have 3 options:
A) Plain-old folders.
B) Gems.
C) Rails Engines.
Correct me if I’m wrong but I believe option C is what most of you have chosen or use so far. I just want to understand why and if you’d still make the same choice if you had the option to start again.
B and C are on some level very much the same: collocating tests with isolated parts of code ensures that you remove coupling between these gems (remember that engines are just gems+Rails).
A - Folders do not give you that. Combine something like packwerk with folders and they can become a transition tool to B or C.
When analyzing B vs C I mostly think about with a “functional core, imperative shell” lens: gems for functional cores, C for imperative shell
Stephan is right on the money. We use B and C also and using pretty much the same criteria. We could more aggressively factor into functional core but Gems (at least in our world) are not allowed to have dependencies on engines so they tend to be things that can be tested in isolation.
<@U78E2Q4FDIQ> That’s a nice read. If I understand correctly, private AR models would be similar to the option A above? If yes, assuming you’ve already discovered the scope and boundaries of the domain you want to extract, would you still choose option A over C as a first step?
Also, say you end up reconsidering a design decision and decide to roll some bits back to the monolith or to other component(s). Is there any significant cost of doing so from a B or C approach vs A?
A should make C easier, so we should consider doing A in-place before extracting.
Narrowing down my question even more: Would that apply for new code as well? Say you want to write a component that replaces logic buried in the monolith and so will eventually be deprecated.
The costs of extracting something vs merging it back together are vastly different (merging is virtually free). As such, for new code, consider starting separated even if you are not completely sure bout the boundary.
<@U782WI24OVK> A + Packwerk seemed to us like a good incremental step towards B/C with less overhead. We might still do B/C but the level of effort for us would be higher so we’d need a compelling reason it’s worth it
We also really like <@U78E2Q4FDIQ>’s article about private AR models and we’ll probably adopt that approach as well it’s just harder to adopt incrementally