I agree with the article’s ideas, but certain things about the execution bother me.
calculate_order_total_for_customer. I’d just call it calculate_order_total. It’s clear than any order will have a customer, it’s in the type signature.
is_user_eligible_for_discount. I’d call it user_is_eligible_for_discount. Because inevitably that function is getting called in an if statement, and you’d rather it read closer to proper English: if user_is_eligible_for_discount:....
“Designing for Tomorrow”. I agree that dependency injection is a valuable technique, but it’s not always strictly necessary and they seem to say you might as well always do it just in case. That’s counter to YAGNI. Make sure you have an immediate use case, or let future you do it if you end up needing it. It’s not hard to refactor something to inject a dependency.
Dependency injection has significant upsides, but the indirection also has significant downsides for direct readability and traceability. Suddenly, you separated definition and call into distanced registration and use, with magic indirection that may or may not use various lifetime behaviors or proxying and wrapping or later replacement on types.
I’ve tried reading (and fixing) a library that made excessive use of DI, and it was very hard to follow or get into.
I agree with the article’s ideas, but certain things about the execution bother me.
calculate_order_total_for_customer. I’d just call itcalculate_order_total. It’s clear than any order will have a customer, it’s in the type signature.is_user_eligible_for_discount. I’d call ituser_is_eligible_for_discount. Because inevitably that function is getting called in anifstatement, and you’d rather it read closer to proper English:if user_is_eligible_for_discount: ....Dependency injection has significant upsides, but the indirection also has significant downsides for direct readability and traceability. Suddenly, you separated definition and call into distanced registration and use, with magic indirection that may or may not use various lifetime behaviors or proxying and wrapping or later replacement on types.
I’ve tried reading (and fixing) a library that made excessive use of DI, and it was very hard to follow or get into.