stop shipping prototypes
developer build feature
developer think:
architecture good
abstraction smart
future-proof system
developer wrong.
first version of feature almost always prototype.
not because developer stupid.
because developer not know problem yet.
cannot design correct system before discovering real system.
first implementation is discovery
before writing code:
- requirements incomplete
- constraints unknown
- real data shapes unknown
- extension points imaginary
- API limitations undiscovered
- performance assumptions fake
developer think system simple.
then implementation begin.
suddenly:
- edge cases appear
- data model stop making sense
- abstractions leak
- API fight back
- "generic" system become giant conditional
- assumptions collapse
this normal.
first implementation not failure.
first implementation purpose is learning.
prototype produce knowledge.
prototype code and production code not same thing
prototype code optimize for:
- speed
- exploration
- discovering constraints
- validating assumptions
- answering unknowns
production code optimize for:
- maintainability
- explicitness
- extension
- operational stability
- future change
these goals conflict.
problem happen when team pretend prototype code already production architecture.
shipping prototype forever
this where suffering start.
team say:
we clean later
later never come.
then:
- bool flags multiply
- weird adapters appear
- transformations duplicated
- abstractions become incoherent
- changing one thing break three others
- nobody understand data flow anymore
- developers afraid touching code
codebase become fossilized prototype.
pile of preserved assumptions.
second pass is where real architecture appear
after first implementation:
- real invariants visible
- actual extension points known
- performance bottlenecks measurable
- correct data structures obvious
- unnecessary abstractions identifiable
- API boundaries clearer
now developer finally understand problem.
this often moment where feature/module/service should be rebuilt properly.
not entire project.
small targeted rewrite.
local reconstruction using real knowledge instead of guesses.
rewrite not failure
many developers hear "rewrite" and panic.
because giant rewrites usually disaster.
correct.
rewriting entire system from scratch because engineer bored is stupid.
but refusing to rewrite obviously exploratory code also stupid.
small rewrite after learning often cheaper than years of incremental patching.
first implementation teach what second implementation should have been.
smart developer
smart developer not person who write perfect architecture first try.
smart developer know:
- first assumptions probably wrong
- first abstractions probably premature
- first implementation mostly exploration
smart developer recognize prototype when they see it.
and know when it time stop patching it.
first code solve mystery
second code solve problem