4 ms·
Right, but then someone sees that, and goes "Ah-hah. This is saving Candidates. Over here I'm also saving Foos. I'll refactor this so I have a generic 'Save' me
by lostcolony 6y ago
Right, but then someone sees that, and goes "Ah-hah. This is saving Candidates. Over here I'm also saving Foos. I'll refactor this so I have a generic 'Save' method/function, and then both Candidate and Foo can call it. DRY!
And that works, because initially saving is just taking a serializable object and dumping it to JSON. But then things get moved to going to a DB or something, and now it has different expectations, and, oh, crap, we have to do some special logic in the transaction because it turns out saving a foo requires us holding a lock on the bar table as well, but not for candidates, and etc etc etc, and saving was -really just two lines of code in the first place-, and the correct solution is isolating it entirely (with maybe a Saver interface to say 'yeah, this thing knows how to save itself'. Though that likely breaks SRP since now Foos know how to be Foos, and how to save Foos, which involves knowledge of the DB, which seems suboptimal, but which is still cleaner than what you had before)
Etc. My only point is that if the area you're tempted to repeat is not provably the same, contextually, keep 'em separate until it is (even if it's like...they implement the same interface). The pain of getting that wrong is almost always less than combining them, building more assumptions on top of that, and then finding out they should have been separate.