4 ms·
My team inherited a project that was initially built to support US customers. Because it was successful, it was then expanded to support EU customers as well. P
by whack 7y ago
My team inherited a project that was initially built to support US customers. Because it was successful, it was then expanded to support EU customers as well. Presumably they loved the rule-of-3 - instead of finding ways to abstract the existing code to support EU customers, they just duplicated and forked everything.
Which brings us to today where our team had to maintain 2 different code bases, doing almost the same thing, in 2 different ways. Every single feature request we get, takes twice as long, because we have to make them independently in two different code bases. Similarly for bugs, testing, and ramp-up time. This is one of the biggest dev complaints that we have even today, and one of the factors that led to management deciding to "junk it all" and start over from scratch.
Code duplication is better than the wrong abstraction. And the right abstraction is better than code duplication. Finding the right abstraction is very hard, so I can see why people would just settle for the middle ground of duplicating code. But I still think that trying diligently to find the right abstractions is what we should be striving for
- majormajor 7y agoI completely agree with your last paragraph, but you (or your management) lost me with the second: "This is one of the biggest dev complaints that we have even today, and one of the factors that led to management deciding to "junk it all" and start over from scratch." Starting over from scratch doesn't seem like it's going to help find the right abstraction[0]. All the nasty edge cases and such that make the existing code ugly are what you need to consider in order to know the "right abstraction", and they're usually what get ignored in the early design stages of a new rewrite. You're at the point where you've learned pretty well what aspects are both shared and stable between the systems. Seems like a perfect opportunity to start to modularize the existing codebases instead - start to split out the shared functionality so it only has to change in one central place, while allowing the two different top-level projects to have their specific quirks on top of that. [0]for most business processes, I think "finding the right abstraction" is actually a dangerous red-herring. Sometimes you have complicated processes. Sometimes clean readable well-organized code is what you need, not an abstraction over it.
- whack 7y agoI mostly agree with you. I wouldn't recommend doing the rewrite for this reason alone. There were other reasons involved in doing a rewrite. The pain of maintaining a duplicated code-base was only one of many pain points in the status quo.
- Bokanovsky 7y agoI've been involved in projects that take it a step further. They realise that two products or code bases are similar enough that they can be duplicated, like the example you've given above. But instead of splitting the code bases, they decide to have one code base, that codegens the code for both projects. At first code gen this way seems ideal, but the trouble is you'll start to realise one project needs a feature that the other doesn't and or it needs something implemented in a different way. The code gen in question doesn't support feature flags in a straight forward way, and adding extra features comes at a cost greater than just writing code to do it properly. Then you'll have to start maintaining not only the two projects, but a proprietary codegen framework.
- diob 7y agoI think the problem is that no real clear cut method for deciding on duplication vs abstraction exists or could exist. It takes a human to look at the context and decide if duplicating or abstracting is the right answer.
- ken 7y ago> Code duplication is better than the wrong abstraction. The explanations of this statement that I’ve read make no sense to me. They amount to “using an abstraction for two things which just happen to be the same today” is bad. Well, obviously. It’s like seeing that your tire pressure is 35 psi, and the speed limit is 35 mph, therefore #define speed pressure. It’s really not difficult to see when A=B by definition or by chance. I no longer follow the Rule of Three, and I can’t recall any situation where I thought I’d wasted any time on an abstraction that didn’t end up working. I have spent a lot of time dealing with duplication when someone copy/pasted a second case (presumably a follower of the Ro3), even though it was obvious from the start that the two cases would always be identical.
- marcosdumay 7y ago> It’s really not difficult to see when A=B by definition or by chance. Some times it is. On those times it's better not to abstract prematurely. Some other times it isn't hard to see the equality is by definition, but it's really hard to see what is or isn't covered by the definition. On both cases, if you get more examples, your life gets easier. That's why people took this wisdom and compressed it into an easily digested pill inexperienced developers can use to treat all their duplication needs, either it helping or harming.
- earthboundkid 7y agoLiterally an example from today: updateDescription(image) { let description = window.prompt( "Update description", image.description ); if (description !== null && description !== image.description) { actions.doUpdate(image, { description }); } }, updateCredit(image) { let credit = window.prompt("Update credit", image.credit); if (credit !== null && credit !== image.credit) { actions.doUpdate(image, { credit }); } }, I waffled on whether to deduplicate it or let it be. What was the Obvious Right Choice?
- KajMagnus 7y ago> I waffled on whether to deduplicate it or let it be. What was the Obvious Right Choice? What about adding a one line comment that this code can be refactored and improved, and how? But not doing anything immediately. If you run into this annoying code repeatedly, then, it can be worth taking the time to refactor it.
- titzer 7y agoI am generally a fan of the rule of three, yet there is definitely some validity to your point. It takes experience and judgment to know when to abstract and when not to. If you happen to have a narrow domain where you have solved the same problems repeatedly in the past, it's often easy to see the right abstraction. In a new domain with new problems, and unclear requirements, it's much harder. Of course, from this distance it's impossible for someone to judge whether your or your management's judgment is warranted. But there is a risk in junking it, called the "Second System Effect". Don't over abstract this time. Also, it's also worthwhile to document and explicitly write out a list of requirements. You can be more or less scientific about this, but the exercise will keep you focused on meeting requirements instead of ivory tower design.