All my attempts to jump off OOP train break at exact same moment when I try to write a unit test. Closure: or, simply use this monstrous component pattern when 70% of your code is boilerplate or hack into namespaces and override functions in them in runtime. And don’t forget to do it in right order! JavaScript: yeah, simply re-define ‘require’ before importing dependencies in tests. Yeah, do it in right order. Recent…
Dependency injection is probably my favourite paradigm out there, especially in a statically typed language: for the reasons you mentioned, and for discoverability with an IDE (or ctags). It is also a natural fit for “OOP”, or rather: classes. In a sense, it turns non-OO code into OO simply by storing the interfaces implementing the dependencies required by your code. If that’s your only state, are you still OO? I’d…
I will explicitly exclude legacy code from my previous statement, where globals, static calls with side effects, stateful objects and inheritance abuse were common.
Now if only I had all the advanced type system features :/.