The design is also a process, the set of activities that produce the structure called design. This process is responsible to create the structure that is a solution to the set of requirements. So, design as a process defines the bridge between the problem space, the requirements, and the solution space, the structure of the code, such that the latter satisfies the former. There are two perspectives on how the process should occur: a top-down perspective and a bottom-up perspective.
The top-down perspective departs from the requirements and identifies the structure that should fulfil the requirements. For instance, if there is a requirement that in the future there will be more versions of a particular entity, this is a hint to try identify an abstraction for the all the possible versions of the entity, such that the impact of implementing new versions of the entity is reduced, following the open close principle. Top-down approaches design the system by successive decompositions where modules are decomposed into more detailed modules. In its pure form, top-down design occurs before the implementation starts.
Bottom-up design intertwines designing and coding, it is usually defined as refactoring. In refactoring developers are either incrementing the system functionality or refactoring its structure. Therefore, the abstractions are made to measure the set of functionalities the system is currently implementing. There is not extra complexity in the code. Refactoring requires a test-driven approach because the changes to the structure should not break any of the existing functionality. Changes to the structure of a software system are disruptive and developers would be afraid to change the structure if the tests did not tell them what is not working after a change.
There is a trade-off between using top-down or bottom-up design. It is possible to use a mix of both. After a first identification of the requirements design a sketch of a design where developers can start working. This sketch follows some well-known and proven architectural solutions. Afterwards, refactoring occurs inside this architecture. For instance, in a web application the team decides to follow a particular architecture, sometimes supported by a technology like Spring MVC, and the domain specific abstractions are identified by refactoring the code that implements the system functionalities.