Hi all,
I'm facing a particular issue in my company at the moment and can't seem to figure out how to fix it. Hope you can help. For the sake of IP, all code presented here will be crafted.
We have part of our code that performs operations with certain properties attached to a specific operation or sequence of operations. Guys at my company have different background languages and took kind of a functional approach (please correct any mistakes of mine) at solving this problem. Let's say I have a Dog structure and I want this dog to do things, but this dog can hold a bone of different sizes and weights. Each bone's set of properties is specific to a certain sequence of (possibly one) operations, and I don't want to mutate my initial Dog instance. In our code this is done with the following:
This presents different advantages, most notably that:
1. the code reads simply
2. it's fast to type
3. ... it answers our first needs (those given above)
But, as in any software system, we added complexity over time and now for our tests we mock the behavior of the Dog. So any function previously taking a Dog now takes a DogOperator (couldn't find a better name for this but naming's not the subject), which is an interface, and we have a Dog and FakeDog, that both implement DogOperator, the sole difference being that FakeDog really does nothing except faking... See the snippet updated:
The problem is that our functions use the WithBone method, and so this one can't return a Dog anymore if we want to be able to mock our Dog... So it should return a DogOperator:
Okay now this works but everytime we need to change the behavior of the Dog, say by adding a function that needs not be mocked anywhere, or a field that could a priori simply be accessed as is, we need to add a method to the method set of DogOperator and update every single implementation. In short, our interfaces (at least those following this pattern) are 100% coupled to their implementations (or vice versa), which I think is clearly not ideal.
Moreover, we have kind of a reflect bunch of hard-to-understand code that I'd like to remove, that checks for such patterns, as we are waiting for them to be followed in some cases, notable in our handlers.
The question I'm trying to answer is "How do I tackle this?", the goal being to avoid a whole rewrite of the code. Small incremental steps that can each be performed in a matter of days would be perfect but each time I think I found a working way, I hit a wall because I end up breaking one of our prior needs and need to do it all at once for things to keep working.
Note: our codebase is about 80K LOC, this is not *so much* but I can't afford to change everything at once, I need to find something to break this task down into smaller ones, hence my mail... 😅
I thank you all very, very much in advance for your time and energy (and advice!)
Have a wonderful day
Cheers