We are planning to implement custom features (in the form of newly developed modules) on top of a standard Drupal7 installation. This "standard" Drupal installation may include some contribution modules such as organic groups. This extended Drupal installation will be provided to different clients each of which may require custom theming and some (minor) customisation of the custom features mentioned above.
What I am wondering about is the deployment and code maintenance architecture. Coming from an object oriented background my initial reaction was to propose a layered architecture along these lines:
------------------------
Client Customization Modules
----^ ^ ^ ^ ^ ^ ^ ^-----
Generic Self-created Modules
----^ ^ ^ ^ ^ ^ ^ ^-----
Contribution Modules
----^ ^ ^ ^ ^ ^ ^ ^-----
Drupal Core
------------------------
Meaning the custom main extension modules ("Self-created Modules") would be overwritten/overloaded wherever the respective client requires individual changes using a second custom layer of "Client Customization Modules". From my point of view this is benefitial as it allows for the generic "Self-created Modules" to remain identical for all clients so bugfixes can easily be performed on a single, central svn location.
Now a colleague argued heavly against such an approach, saying having a 4th module layer which basically overwrites hooks of the 3rd layer would be extremely bad practice in Drupal development as it raises the application complexity and makes debugging virtually impossible.
The alternative would be to create redundant copies of the "Generic Self-created Modules" layer for each client and directly customize these instances. While this is surely possible, a bugfix or change to the generic functionality would then not be possible anymore in a central location, so this approach seems quite dirty to me.
Is it really considered bad practice, or heavily advised against, to customize ones own custom modules by "hooking custom hooks" in a way proposed above?