Three item stores look near-identical — what would tell you that folding them onto one type parameter is the wrong move?
answer
- blank out the kind and compare
- is the kind the axis of variation
- watch what grows inside the merged body
- flags and hooks are copies re-entering
- do the three change in the same week
basics
~20 sThat they differ in more than the item kind. If the bodies diverge in rules, invariants or reasons to change, the shared version pays for its single body with per-kind switches, and three honest bodies read better.
solid answer
~50 sThe test is mechanical: blank out the item kind in all three and compare what is left. If the remainder is the same algorithm, one placeholder is the right answer — the three were one body wearing three names. If the remainder still differs, a different expiry rule, a different tag scheme, one that must stay in arrival order and two that need not, then the kind was never the axis of variation, and parameterizing over it merges code that was only superficially alike. You can tell the merge went wrong by what grows afterwards: flags, optional callbacks and branches on the kind inside the shared body, each one a copy you did not really remove. A second signal is history — three stores that have never been changed in the same week are unlikely to start.
go deeper
Recall that a placeholder abstracts over one thing, the kind held, and only helps when that really is the only difference. Erase the kind from each copy and see whether what is left matches.
Explain how a wrong merge shows up: branches on the kind, flags and unused hooks inside the shared body, each of which is a duplicate re-entering in disguise.
Show that you weigh change history alongside shape, and that you would fold the two that match rather than forcing all three. Say what repair you would apply to a merge that has already grown branches.
The call is about where variation is allowed to live. Standardising three teams onto one parameterized store makes every future difference a negotiation, and that coordination cost has to be worth more than the duplication it removes.
## The question behind the question A placeholder buys one checked implementation in place of several near-duplicates. That trade is only good when the near-duplicates really are duplicates, and "near-identical" is doing a lot of work in the premise. The interviewer is checking whether you reach for the parameterized version by reflex or because you tested the assumption. ## The blank-out test Take all three desks and mentally erase the item kind everywhere it appears — field, parameter, return. Then compare what is left. - If the remainder is **the same algorithm**, character for character modulo names, the kind *was* the only axis of variation. Parameterize; you will delete two thirds of the code and lose nothing. - If the remainder **still differs**, the kind was not the axis. Something else varies, and a type parameter cannot express it, so the merge will have to express it some other way — which is where the trouble starts. The second case is common and easy to miss, because the differences hide in small places: one desk keeps arrival order and the others do not; one rejects a second deposit on the same tag and the others overwrite; one holds items for a different period; one must survive a restart. ## What a premature merge looks like afterwards A merge that outran the real similarity does not fail loudly. It grows. Watch for these, each of which is a copy re-entering the shared body in disguise: 1. A **branch on the kind** inside the shared sweep or the shared deposit. 2. A **boolean flag** passed at construction whose only job is to pick which of two old behaviours runs. 3. An **optional callback** or hook that two of the three use sites pass and the third leaves empty. 4. A parameter that is **meaningless for some kinds** and must be documented as ignored. Each one makes the shared body harder to read than any of the three originals, and now every kind pays the reading cost of every other kind's special case. Three files you could each understand in isolation have become one you cannot. ## Signals to weigh before folding | signal | reading | |---|---| | the bodies differ only in the item kind | fold — this is exactly what a placeholder is for | | one keeps arrival order, the others do not | a second axis of variation; folding buys a branch | | they have never changed in the same week | they are not one thing that varies by kind | | two are identical and the third drifted | fold the two, leave the third | | the differences are all in the caller, not the body | fold — the body really is shared | The change-history row is the one candidates rarely mention and interviewers like. Code that changes together usually belongs together; three stores whose commits never coincide are three subjects that happen to share a shape today. ## The partial answer is usually the right one The choice is not three bodies or one. Folding the two that genuinely match and leaving the odd one alone gives most of the deduplication with none of the branching, and it leaves the third free to evolve into whatever it is actually becoming. If the third later converges, fold it then, with evidence. And if the merge has already happened and the branches have appeared, the repair is the same test run backwards: find the branches, ask which kind each exists for, and split that kind back out. A shared body with no per-kind branches in it is the state you are aiming at, in either direction.
- Two of the three are genuinely identical and the third is not. What do you do?Fold the two onto a placeholder and leave the third alone. A partial merge takes most of the duplication out and keeps one honest body free to diverge, which beats a three-way merge held together by a flag. Revisit the third only if it later converges on the shared shape.
- The merged body has grown two branches on the item kind. What does that tell you, and what is the repair?That the merge outran the real similarity: the kind was not the only axis. The repair is to ask what each branch exists for and move it — to a construction parameter, onto the item itself, or back out into its own body. The target state is a shared body with no per-kind branch in it.
saying these in an interview costs you the question
- All duplication is a defect, so near-identical bodies must always be merged
- A flag in the shared body is a fine home for a per-kind rule
- Two bodies identical today will stay identical tomorrow
- Merging always reduces the amount of code a reader must hold
- Near-identical can be taken to mean identical apart from the item kind