When producing any software you will ordinarily go through three stages in order to deliver excellent value. These are hack, refactor and integrate. The quality of output will depend whether and how well you perform each of these steps. Poor quality software is marked by most if not all of the codebase never moving past the first stage. Majority of projects tend to have the core having passed through the full pipeline with only newer features living in the first two stages.
These three stages exist for a simple reason: no-one writes perfect software the first time. Even the most experienced software developers need to go through these stages the main difference being that they can go through them faster and more times than inexperienced software developers. As you grow in your experience you tend to develop tips and techniques on how to race through all stages so that you can produce higher quality with time.
When code does not complete the loop the level of technical debt grows to the point that further development is rendered too hard or expensive to continue. However, code that has all aspects having gone through all stages to a remarkable degree becomes extremely easy to extend.
The goal of the hack stage is to prove the viability of the concept. Typically, the developer's goal is to show, with the minimum of investment, that they can get the required functionality in place. In this stage, the developer may be the only one who can run the program successfully. Quite often the output may only be able to run on the developer's computer. The manner in which the run may be effected may be crude and tedious often involving shorthand known to the developer. However, it doesn't follow that the quality is bad. It may be that the software is fully unit tested to keep track of an expanding feature scope.
Once the concept has been demonstrated it is time to tidy things up a bit. The goal of the first major refactor is to answer the following question: how should the functionality be decoupled? Decoupling is the processs of subdividing the elements into layers conveying the knowledgeability of each layer. Layers form a natural structure for organising software elements. Layers close to the top present simple natural interfaces which handle top-level ideas while deeper layers handle very particular details and may only provide services to higher layers that may never be touched by ordinary users.
The integration step responds to the following question: do any new features imply a change in the mental model of the solution? A change in the mental model will ordinarily require a major change while no change will simply require that any external interfaces are modified to absorb the new features. Typically, the first integrate step (i.e. the integrate step that is part of the first complete iteration) will not require major changes to the mental model.
A related idea is that of the software's feature scope. Feature scope is marked by the domain or niche the software is targetted at. The broader the application the wider the feature scope. Highly focused niche software tends to have a very narrow feature scope. A wide feature scope means that the software will required very many iterations through the software development stages compared to that with a narrower feature scope.