All code is born ugly.
It starts disorganized and inconsistent, with overlaps and redundancies and gaps.
We begin working it into an imperfect solution for an often poorly defined problem.
As we start building up like clay, a solution starts taking form. The feedback guides us in moving, removing and adding material. It allows us to add and remove details. We learn from our mistakes.
As we iterate, the problem itself becomes clearer. We focus on the problem from the optics of possible solutions.
Every project follows this path. All code is born ugly. This is the technical debt that every project incurs in those early days, and that is only paid off through iterations. For many projects the final form is an evasive goal that’s always just out of grasp.
Occasionally someone will believe that they have so much experience that they can circumvent the ugly code step. Extensive up front design, planning, standards and guidelines. Start as a swan.
This yields the ugliest code of all. It yields the poorly suited, overly abstracted solutions that solidify like concrete, forever ill-suited for the problem because the feedback loop was circumvented. Grotesquely overwrought solutions for the most trivial of problems, enormous line-counts of boilerplate, unoriginal code for the most banal of needs. These projects become the ugliest ducklings of all.