Rule of three sounds catchy but logically it's just a arbitrary number.
Similar to SOLID and KISS, why pick some arbitrary (and also obvious) qualitative features and put it into an acronym and declare it to be core design principles?
Did the core design principles just Happen to spell out Solid and Kiss? Did it happen to be Three?
Either way, in my opinion, designing an abstraction for 3 clients is actually quite complex.
The reason the OP advocates pure functions is because pure functions are abstractions designed for N clients, when things are done for N clients using pure functions the code becomes much more simpler and modular then when you do it for three specific clients.
This is a good question, and I haven’t yet seen anyone reply with (I think) the real answer: it’s not the rule of 3 so much as “not 2”.
When you start adding a new feature, and notice it’s very similar to some existing code, the temptation is to reuse and generalize that existing code then and there -- to abstract from two use cases.
The rule of 3 just says, no, hold off from generalizing immediately from just two examples. Wait until you hit one more, then generalize.
“Once is happenstance, twice is coincidence; three times is enemy action” (Ian Fleming IIRC)
I think setting hard limits on design is a good thing. Creativity needs limits. If your limits can imply something about your desired design goals then that’s a good synergy. It also forces the engineers to think more about design rather than fall back on their goto pattern that may or may not fit the problem.
Especially junior and mid level engineers might not have good heuristics on is their design any good or is it just following whatever cargo cult they were brought up in.
Like one engineer on my team implemented this crazy overkill logger and I asked a few questions why do it like this and the answer was that they had implemented it in another language at another company. After that I told them to not have more abstraction layers than concrete implementations when adding a new feature.
Sure, but I wouldn't implement something like that as a policy, but as a guideline. So when someone really goes overboard into one or the other directionyou can point them to the guideline, but there is still some freedom in deciding on the spot.
If the need / opportunity to abstract something is highly subjective then it is best left to the team lead / senior architect. For all other obvious cases having a policy as outlined above strikes a healthy balance between autonomy and uniformity.
While I usually like the zero-one-infinity rule as a go to when there aren't any other constraints, when trying to build an abstraction it can be fairly tricky to suss out the parts that actually are share vs what is actually different. Two unique and independent users could share a lot of process &c randomly, 3 is a little less likely.
Ye I don't like these way too specific rule of thumbs either. It is superstition that is invoked during code reviews to not having to explain or justify your arbitrary nagging on the reviewing side or defending a bad layout on the other.
Rule of three sounds catchy but logically it's just a arbitrary number.
Similar to SOLID and KISS, why pick some arbitrary (and also obvious) qualitative features and put it into an acronym and declare it to be core design principles?
Did the core design principles just Happen to spell out Solid and Kiss? Did it happen to be Three?
Either way, in my opinion, designing an abstraction for 3 clients is actually quite complex.
The reason the OP advocates pure functions is because pure functions are abstractions designed for N clients, when things are done for N clients using pure functions the code becomes much more simpler and modular then when you do it for three specific clients.