Unlike plan-driven development agile software development has no separate design phase. Rather all design decisions are made implicitly during implementation and typically test-driven development (TDD) is used to drive the design. In a nutshell this means development is the continuous repetition of the following steps:
Design decisions are made in steps 1, 3 and 5.
While writing an automated test, design decisions about the interface of a module (the module under test) are made. How should the methods be named? Which parameters shall they take? Which exceptions are thrown? What are the return values? etc. All these decisions are about the interface of a module. They may also have effects on the implementation but ideally they should not.
The central principle during this phase is EUHM. By writing the tests first, almost naturally solutions arise which are intuitively usable. Design centeres around the question “How do I want to use the module”. This drives the design to be EUHM-compliant. Other principles may also be considered, but this is not the focus of this phase.
Design decisions in this phase comprise decisions upon algorithms, data structures, private methods, etc. The interface of the module that implements the feature has already been designed. So this phase deals with finding a suitable implementation that complies with the interface specified by the test.
During this phase the feature is implemented. Agile methodologies typically call for simple solutions here. So the central principle during this phase is KISS.
The last step in the TDD cycle is refactoring. Decisions made in previous phases of the cycle or previous incarnations of the cycle may be reversed in order to improve the design without changing functionality. This does not mean that this is solely a correction phase for bad decisions taken earlier. Rather solutions which were “good” when they were implemented may not good anymore because the software has changed in the meanwhile. Modules which may have served a valuable purpose may become useless and need to be removed. Others may grow so they need to be split up into several smaller modules. The requirements for the software changes and thus the software changes. The refactoring phase now keeps sure that the structure of the software changes accordingly so that the design does not degenerate.
For this phase there is no central principle. Rather the principle language as a whole is used to find problems in the design which need to be treated using refactoring.