Customizing custom modules 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?
In Drupal, most of the customization is not done by overriding existing code but rather by extension or alteration.  Most contribution modules and Drupal core provides extension points (hooks) and configuration variables. Your custom modules (self-created and client customization) should re-use these hooks and configurations.

For your self-created modules, you can use the Features module to easily export configurations into code. To customize your features at the client customization level, you can choice to either use alteration hooks or to re-write part of the Features-generated code to make it customizable via in-DB configuration. See http://developmentseed.org/blog/2009/jul/09/development-staging-production-workflow-problem-drupal and http://www.archive.org/details/CodeDrivenDevelopmentUsingFeaturesEffectivelyInDrupal6And7 for more information on the Features module. Also, the Kit Specification provides information on how to build re-usable features modules (with Features)., see also http://funnymonkey.com/building-features-for-install-profiles and http://nodeone.se/blogg/an-alternative-way-of-structuring-features-for-distributions.