Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

That works until you have a function that implements timeout and so needs to query time multiple times per invocation.


Agreed, so the preference order is 1. Pass in the data you need 2. Pass in a function that gives you the data you need 3a./3b. Pass in an object (or function like a factory) that gives you the function that gets you the data you need.


> Pass in a function that gives you the data you need

That's basically dependency injection but on a per-method basis. I'd see this as an anti pattern because it makes function calling _way_ more complex and error-prone.


> it makes function calling

First: no, not necessarily. Second: when you limit yourself to function calling, then yes, the problem is more pronounced (but not always there, see 1)

In OOP, you can have factories, or constructors, or even entire design patterns to help solve this. In FP, there are closures, that can solve this exact problem for you: the dependency -e.g. a timekeeper- is captured in the closure.

Dependency injection is, by no means, limited to `do_the_thing(variable, depency1, depency2, dependency3)`.

I see this argument too often used to counter the idea of DI, and it is silly: it shows above all that the person countering the idea has little experience with all the surrounding concepts to support DI.

And that brings me back to 1: There's so much more that can be DI-d: objects can be instantiated with dependencies passed in, factories can do this. There are Actors, Workers, Decorators, Factories. Hell even a superglobal `config.get_timekeeper()` might work in some situations.


The function you pass in can keep track of how many times it’s been called, and provide different values on each call.


This is way way worse than passing in a timer and destroys your ability to write multi threaded code (among other defects).


This is for unit testing. Even if your unit tests run in parallel, each test case will have it's own mocked clock.

This is not even an experimental approach, the mocking of timers is literally one of the canonic examples of the advantages of dependency injection. I have written this exact code multiple times, on my own, or refactoring others people untestable code to this pattern to be able to test them. A couple of times the reason for the refactoring was specifically to demonstrate the existence of race conditions, to have a test case that has the race condition be deterministic so we could fix it and be sure of the fix working.


You can extract the timeout functionality into its own structure then and mock it out during testing.

There's usually a solution of some sort, it might just require a bit of rearranging and extraction of concerns.


That’s basically dependency injection


Yes, that's my point - they're giving an example for why "you can't do it", and I'm saying even for the example they just gave you can.

Create a Timeout class and subscribe to it for a given interval with a callback to what needs to be run. Pass it in as a dependency which can be mocked during testing.

Not sure why the downvotes...




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: