Functional Design: Principles, Patterns, and Practices (for True Epub) by Robert C. Martin

Functional Design: Principles, Patterns, and Practices (for True Epub) by Robert C. Martin

Author:Robert C. Martin
Language: eng
Format: epub
Publisher: Addison-Wesley
Published: 2023-03-15T00:00:00+00:00


A DIP Violation

While all this winning was going on, did you happen to notice the DIP violation? You might have missed it because it’s not in the production code. It’s in the integration test.

Look at the ns statement. Do you see those two lines that mention the statement-formatter and the statement-calculator? Those lines create source code dependencies on the concrete implementations of those modules. That’s a high-level policy depending on a concrete low-level detail. That’s a definitional DIP violation.

Perhaps this puzzles you. How can a test be a high-level policy? Aren’t tests as low level as you can get? Aren’t they the ultimate details?

Yes, that’s true. But integration tests in particular are stand-ins for high-level policy. Look at that integration test again. It does precisely what the high-level policy of the application would have to do. It calls make-statement-data and passes the result to format-rental-statement. And since both of those functions are concrete implementations, our high-level production code will have the same DIP violation as our integration test.

Do we always pay attention to the DIP in our tests? It is always wise to be aware. It may not always be wise to force compliance. Some tests are best left coupled to low-level implementations. However, if you want your test suites to be robust and flexible and if you don’t want a hundred tests to break when you change one small thing in the production code, then keeping an eye on the coupling between your tests and the production code is a good idea.25

25. I spend a lot of time on this topic in my book Clean Craftsmanship (Addison-Wesley, 2021).

But perhaps you are still not convinced. So let’s add a new feature. Sometimes we want the statement to be displayed on a text terminal, and sometimes we want it on a browser. So we need text and HTML versions of format-rental-statement.

Let’s also add one more new feature. Some of our stores are offering a “buy two, get one free” policy. So, if you rent three videos, you will only be charged for the two most expensive ones.

If we were implementing this in an OO language, we would likely be tempted to create two new abstract classes or interfaces. The StatementFormatter abstraction would have a format-rental-statement method that would be implemented in both the TextFormatter and HTMLFormatter implementations. Likewise, the StatementPolicy abstraction would implement the make-statement-data function in both NormalPolicy and BuyTwoGetOneFreePolicy.

We can easily mimic this design by using any one of the three approaches that we discussed in the section on the OCP. We could build vtables for the two abstractions. Or we could use defprotocol and defrecord to build actual Java interfaces and implementations. Or, finally, we could use multi-methods.

Let’s see what the multi-method approach looks like. Keep in mind that this is a child-sized problem posing as an adult situation. What you’ll see me do here is meant to show how much larger problems can be designed and partitioned.

In the end, as shown in Figure 12.6, I split the whole system up into eleven modules, three of which are tests.



Download



Copyright Disclaimer:
This site does not store any files on its server. We only index and link to content provided by other sites. Please contact the content providers to delete copyright contents if any and email us, we'll remove relevant links or contents immediately.