In classical approaches to software development, an architect or a team lead may spend time upfront designing the system. This can include such all modules and communication layers as well as all interfaces into the system. The theory is that given enough time with the design and framework, development will be accelerated because all of the functionality can simply be dropped in.
This is rarely the case. In reality, designing a system completely upfront to avoid risk ends up with an inherently risky system.
With Emergent Design, we start delivering functionality and let the design emerge. We take piece of functionality A and implement it using best practices and proper test coverage. We then move on to delivering functionality B. Once B is complete, we look at what A and B have in common and refactor out the commonality, allowing the design to emerge. This process continues as we continually deliver functionality. At the end of our release, we are left with the smallest set of the design we need, as opposed to the design we could have imagined up front. We end up with a smaller code base, which naturally has less room for defects and a lower cost of maintenance.
Do not practice Emergent Design without a comfortable set of unit tests. As Emergent Design is heavily dependent upon Refactoring, doing so without unit tests is an irresponsible practice.