Invert Dependency 2
- A consumer depends on how a supplier implements a service.
- Both the consumer and supplier depend on a service specification defined at the consumer’s level of interest.
Invert Dependency structurally enables options for both the consumer and the supplier. For the consumer, because they depend on the general service specification instead of any particular implementation, anything that meets that general specification will suffice. For the supplier, by promising that their unique implementation will satisfy the general service specification, they can provide their solution to any consumer that depends on the general specification.
Preconditions: A person (consumer) loves fresh bread, but their local bakery (supplier) requires that payment be rendered in cash. Because the customer depends on the details of how the bakery handles money, the relationship is fragile to disruption in the customer’s access to cash.
Postconditions: The bakery allows any form of payment that customers may have by adopting a modern Point-Of-Sale system. The transaction depends on the general concept of rendering payment (rather than specifically on cash).
Preconditions: Marketing (consumer) wants new features designed by their UX staff, but their requests assume knowledge about development costs that are specific to and understood by the software engineering team. The cost and schedule of new feature development are highly dependent on these engineering details and are therefore fragile to errors in marketing’s assumptions.
Postconditions: Marketing only specifies the user goal of a new feature, omitting details about how those goals are to be satisfied. Development is free to explore multiple technical and user-experience options in meeting the user’s goal.
Postconditions: The development team defines their own generic high-level HTTPS interface and creates a thin wrapper that implements that interface and calls the original open source HTTPS library. The client module depends only on the generic HTTPS interface and it’s easy to develop alternative wrappers around other libraries. The client module is no longer fragile to any third-party HTTPS API or the stability of the providers of those libraries.
CLOSE ALL EXAMPLES
The main challenge is to determine what the consumer’s interests really are in relation to the supplier and to capture those interests in the service specification. A useful technique is to start with the current requests made to the supplier and repeatedly as “Why does the consumer need this?” until your answer reflects the direct interest of the consumer. Capture that answer as the request instead of the original one.
For example, imagine a Marketing department of an ECommerce company makes the following request of the web development department: “If the user is a rewards member, display a markdown badge next to each product the day before non-members see it.” Why does marketing want to do that? “So that rewards members can purchase products at markdown prices a day early.” This answer to the “why” question the Marketing department’s real interest, while the original request was how they envisioned their interest manifesting in the user experience.
- Mechanical and electrical interface specifications that allow us to connect all sorts of diverse things together
- The concept of “Minimum Critical Specification”
- User story formats such as: “As a <role>, in order to <goal>, I want to <sub-goal>”
- The “Dependency Inversion Principle” which is part of the SOLID Object-Oriented Design principles
This refactoring is derived from the “Dependency Inversion Principle”, the “D” in SOLID Object-Oriented Design principles. It has proven to have such high utility in enabling optionality in software that we chose to generalize it to any domain.
It turns out that dependency inversion is extremely common in many contexts already. The fact that you can plug different appliances into your power receptacles is just one example of thousands. However, there are myriad examples where the fragility between consumers and suppliers is caused by unnecessary dependency on how a service is implemented rather than essential outcomes of the service.