> That's what refactoring/rewriting is for. You have your piece-parts, you start combining them at the next layer up. Realize some of them aren't what you need. Maybe you need more, maybe they should be combined in some fashion, or maybe their behavior should change. So you do. It's not like people (well, fools might, but who wants to be a fool?) say, "You know, I already finished that bottom layer, I should never, ever, ever change it. That would be admitting I was wrong and not psychic. I can't have that." Since most people aren't fools they will, instead, say something like, "Oops, that doesn't compose well. Time to fix it."
I'm not saying it never gets fixed, I'm saying it's extra work compared to top-down.
Top-down produces only and exactly what is needed to get the current layer to compile, run, and pass/fail.
Bottom-up requires that the bottom-most unimplemented layer be written to provide at least what the next higher level needs.
And since you cannot predict that perfectly all the time, you will have to come back and refine (not refactor) that layer: remove some functionality that turned out not to be needed, or add some other functionality that turns out was needed.
This step is never going to happen in a top-down effort.
[PS. At work I've almost always done bottom-up, because that suits the workflow constraints better: 1) Never leave commit a non-working build, 2) never do a PR for an incomplete module, 3) Always make PRs as small as possible, etc.
For my own projects/hobbies/experiementation, I used to do the same thing. Now I'm experimenting with the top-down approach and my velocity is a little faster because I am never spending time removing stuff that was written.]