Every description I have read about god classes considers them to be an anti-pattern and a bad practice. Most descriptions I have read about mixins considers them to be acceptable in some cases. If the functionality of a god class is broken up into several mixins, each mixin can be separately unit tested and separation of concerns is still maintained, at least to some degree. When it comes down to it, I'd still like to encapsulate all of the functionality into one object. I'd like to get opinions on this design. Is this design a bad practice?
Sorry to be the bearer of bad news:
The larger your application gets, the more trouble this will cause. What happens when you try to name a method
do_thing, import it into your god class, and find that it already has a method named
do_thing? Now you have to worry about namespace collisions in your god class: what a pain!
Another (small) one: if everything goes here, and multiple people are working on different modules, but everyone has to "register" things in your god class, then you will be dealing with lots of unnecessary merge conflicts for that class in your code repository. If separate things were always separate, then you have less to worry about from people stepping on eachother's toes.
These are just a few things that come to mind. Really though, you are approaching it from the wrong perspective: why would you want to do this? If you have everything nicely separated and organized, why would you want to undo all of that and throw it all into a single class? Doing this might save you a few
import statements at the top of your code, or a few less dependencies that need to be injected, but none of that is substantially improving your code base, and it comes at a real cost. It's a simple formula:
cost + no benefit = bad idea. You're already doing the "hard" part of dividing your application nicely. Don't mess that up on the home stretch.
From your comments, it sounds like you might want to approach this from the perspective of an IoC Container. If your application has a set of functionality available within it, and you need to have pieces, determined at run time, use that functionality, the best approach is likely a an inversion-of-control container with dependency injection.
- Your application consists of a set of libraries, likely individual objects that are tied together into larger functionality.
- The functional groupings conform to the mixins that your described earlier.
- Individual "project" classes will be added to the application for specific command-control-reporting functions, and as those projects are added in, their dependencies on those interfaces will be bound, using dependency injection.
- Each project class will run in the environment as if it has access to the various different interfaces. Control will pass back and forth between the main application and project class.
This is sometimes called an application framework.