My attempt at loose coupling did no such thing

tags: #tdd #functionalProgramming #financialPortfolio

I am just now trying to implement snapshot functionality with the EventStore. I am running into refactoring challenges because of the object layered implementation which I learned in my Object Oriented Design days. I had been taught a long time ago that dependency injection with good interface design would allow loose coupling. What I recognize now is that dependency injection only allows me to change the encapsulated implementation of the dependency but does not help at all when the interface needs to evolve due to the natural way that code refactoring and business requirements evolve during the initial implementation. Dependency injection does allow me to swap out implementations once the interface is mature. I waited until now to implement snapshot functionality which should be fine and acceptable because I focused first on the business logic. I did not yet need to worry about the I/O utility of snapshots. I think we all too often do not recognize that some of the terminology and goals we are trying to achieve is on a spectrum and not binary. For example “Loose Coupling” seems easy to understand but it really needs a clearer definition. What I want is to be able implement something as utility as snapshots without having to refactor all my objects nor my test cases. If I find that I do have to do this even with dependency injection then I have not achieved “loose coupling” at all. My research tells me this is the whole point of functional programming. Building atomic-idempotent functions does not require interfaces. What I am curious to discover, however, is whether piping of functions creates the same contractual dependencies as interfaces. For example if I have two functions g(x) and h(x) and if I pipe the functions as g(h(x)) I have now made g(x) dependent on the output of h(x). My guess is that I will need to try and avoid objects or structures being returned from my functions. Perhaps just returning tuples will all lose coupling even further. Based on all of the above I have decided that once I am done with this implementation I will refactor the entire project with the objective of having no mocks and trying to implement as declarative rather than imperative as possible.

Written on March 28, 2021