By monolith I mean a full stack MVC (Model-View-Controller) application.
For example, in Ruby on Rails (RoR), the code is organised by (category?, I don't know the right technical term for it) what part it plays under MVC. For example, all models go under one folder, all controllers under one and same for the views. It looks like this...
app/
├── controllers/
| ├── posts_controller.rb
| └── ...
├── models/
| ├── post.rb
| └── ...
└── views/
├── posts/
└── ...
I've been working with this in Rails and I've noticed that as the project gets larger and larger, you have to hop around a lot between folders. For example, if I'm working on the Posts
module, I'll need to make some change in the model, then open the controllers folder, search for the posts_controller
and then go do something in the views folder. It becomes quite cumbersome to deal with.
I think what better suits my workflow, would be to have a folder for the Posts
module and have its model, view and controller inside it. Like, so...
Posts/
├── controller.rb
├── model.rb
└── views/
Which way do you prefer?
Top comments (5)
Definitely the second option. Most of my web work is in the Python Django and it forces you to lay out your code in related "apps". Apps are just sub-directories with each containing related routes, database models, and functionality.
I watched a talk a couple of weeks ago on LaraCon Online where they talked about domain driven design. Seems like a good structure for all your business logic so when you are working on the blog you go to the blog folder, but within that you could have sub directories for models, event listeners, etc. to keep it organised.
Shopify has a great article named Deconstructing the Monolith: Designing Software that Maximizes Developer Productivity in which they reorganized their monolith in components, not dissimilar from your example. They divided the code by real world concepts instead of function. Like mini apps inside the monolith.
I think it's quite common for apps after a certain size to reorganize directories by "domain objects" instead grouping by functionality.
I prefer the second option since it keeps logic that belongs to each other together. Meaning I don't have to jump through a bunch of different folders when I am just working on one feature.
You can also read my post about why you should care about loose coupling.
Of course the second one. Things which are changing together should be keep together.