I like to use abstractions that lead to lots of small objects that do little jobs communicating with each other to do bigger jobs. The common argument I hear against this is that it makes the code hard to change, for two reasons:
1. “The work is spread out into too many places”
The Single Responsibility Principle says that a class should have only one reason to change. The inverse of that is that if multiple things will change for the same reason, they should probably be in the same place. If you are making a change that requires editing lots of things in lots of different places, you’re either making a very high-level change – in which case, this is expected – or your design needs work – those things probably should have been in the same place.
This doesn’t contradict “lots of little objects”, it provides a counter-balance for taking it too far.
2. “It’s hard to find where I need to make my change”
“I’ll start in my view… ok that’s calling a method in this file… oh that’s calling a method in this file…” and so on.
This is sometimes true, but I prefer it to the alternative of everything happening in this one method so it’s easy to find, but when I want to make the change I’m terrified because this method does so much.
I’m willing to trade that anxiety and potential for bugs for the cost of a bit more upfront time looking for the right place to make the change. Because when I find it, it’s only doing one small thing. I can change it with confidence.
This is the main reason I think using lots of small objects enables change. And ability to change is the best indicator of a good design.
Sandi Metz has a great talk on this subject.