I think the problem is cross-cutting concerns. The user needs an ios-notification and an email. Ideally that’s 2 components and a Message Bus. In practice, a chunk of code and stack-overflow :)
Indeed. The un-replaceable components seem to always be the ones that have the oddball business logic in them. These oddball cases, in my experience, are the special cases. And they are special cases more often than not because the feature request reflects a poorly understood aspect of the business making the request.
Business is much more a culture of doing rather than understanding, which is at odds with good module design. Hence, lots of modules in a long-lived project become polluted with special cases until some semblance of understanding is obtained. By that point, the incentives to modularize the crap code is usually not there, from a business standpoint.
If we’re putting selection pressure on modular code then perhaps we should also put selection pressure on non-modular code. Culture which drives toward reusable libraries and open sourcing might help here (maybe) since it means that the more modular a piece of code is the more use it will get and the more eyes will see it.