I have found that many contributed modules create an extra "submodule" for every, as it could appear, single piece of functionality (e.g. ubercart module). This practice is especially common when a such a module provides an integration with other modules (such as with Rules or Views for example). I understand that an author tries to model the dependency this way, but there are other tools available, like for example the function module_exists().
For me it would seem reasonable to do as much as possible in the scope of a single module to avoid tedious switching modules on and off and reduce maintenance and performance overhead. There can be found many small modules now in the core of D7, however there also are some big, old modules, for example the user.module, that comprise really diverse chunks of functionality.
Are there any guidelines for contributed modules how this issue should be addressed? Or if not, what is the good practice?
Comments
I generally break up my
I generally break up my modules this way:
* If it's functionality I will use on another site at another time, I create a separate module.
* If parts of the above module may not be required on another site, then I break the functionality into multiple modules
* If it's functionality specific to the site I'm working on, then it all goes into a single module for that site.
Not really rules per se, it's just how I do it myself.
Contact me to contract me for D7 -> D10/11 migrations.
Generally smaller modules are
Generally smaller modules are easier to maintain due to having less code. I would agree with Jay and generalize to making submodules that cover either distinct and/or optional functionality. Another case to consider is and API that can be re-used could go in it's own module.
For me, I think of it in
For me, I think of it in terms of a Separation of Concerns. A modular framework is designed as such specifically for this purpose: so that users can use only those parts of a program - the collection of modules as it were - that are necessary to achieve the goals relevant to their current project. By separating what could otherwise be one large module into several smaller modules, developers can ensure that users can make use of only those pieces that are necessary in their situation.
Of course, modules have to be logically separated, which is why I referenced the single responsibility principle. No two modules should be dependent upon each other to accomplish a single responsibility. That is, one module can be dependent upon another so long as that other module is not also dependent upon the first module. If it were the case that each were dependent upon each other we can logically conclude that they should be the same single module.
The decision is certainly not an objective one, though. Not all functionality that can be separated into its own module should be. But for me, the minimum requirement for separation is: can a user make use of this code as a stand-alone module? or are there realistic use cases for using the primary module of a package without its additional modules? This is why it can make sense for a pure API to be in its own module - like Rules. Developers can build modules that use the Rules API to execute custom module rules, even while the API resides in a package with another module that the user may never make use of (the Rules Administration UI). It's also why it can make sense to include Signup Webform or Signup Rules as separate modules in the Signup package. Many users may not use Webform or Rules on their sites, so it is reasonable to suspect that plenty of users would never event make use of that particular code if it were included in a single Signup module.