Here is a series of logical, defensible actions that end up with a sub-optimal result:
- We need to share some code between two applications (
App A
andApp B
), so we move it out ofApp A
into somewhere else (i.e. its own repo, or into components or essentials or some similar collection.) - The interface exposed by this shared code isn't quite right for
App B
. Perhaps it's not ergonomic for the application for some reason, so to keep things DRY, they create a wrapper to provide whatever configuration, defaults, or argument shifting makes sense forApp B
. Now, all call sites inApp B
go through the wrapper. - Time goes by, and something else changes. Perhaps
App A
changes a bit, and so the engineers do step 2 above (but -- to be clear, they implement it in a different,App A
specific way). Alternately,App B
becomes more complex and the lower level wrapper is no longer sufficiently ergonomic. However several call sites rely on it, so a higher-level wrapper is created for future use. - Rinse and repeat
The ultimate result is the underlying library becomes very difficult to use. While someone may have done the up-front work of creating docs for the library, those docs no longer apply to most call sites in new code. Different applications have created wrappers, and perhaps those wrappers operate at different levels of abstraction, or are themselves wrapped around other wrappers. All of this is in the intended service of DRYness, but at the cost of a large amount of indirection. Thus, rather than lowering the cognitive load of context switching (because App A
and App B
are using a shared library) it is instead increased, because App A
and App B
have created different, incompatible, application-specific interfaces into that library.
Solutions:
- Create a new method in the underlying library, and perhaps deprecate the old one if necessary.
- Inline code from
App A
intoApp B
, let their interfaces evolve organically, and pull the code into a library when stable. (Requires a lot of discipline) - I don't know! Suggestions please