A program built using an Agile process should be the simplest program that meets the current requirements. There is not much building for the future. Instead, the focus is on providing business value. Of course it is necessary to ensure that a good design is used, and in Agile this is brought about through Refactoring.
Kent Beck provided 4 rules for Simple Design, in descending order of priority:
Simple means enough to allow you to keep moving. Don’t design for something that isn’t needed today. The use of Design Patterns also contributes to simplicity by using standard constructs and approaches that have been observed over many years of software development. Similarly, good object-oriented design principles will ensure that the code is simple and maintainable. A useful guide is the SOLID principles from Robert C. Martin:
Simple design is also a side-effect of Test Driven Development (TDD). Since the code is being written to make the unit tests pass, it tends to be more focused and much simpler.
One of the oft-cited myths about Agile is that there is no design at all, which simply isn’t true. What Agile promotes is enough design for the moment rather than trying to design the entire system up front that many traditional methodologies espouse. Additionally, Agile promotes the use of the simplest tools possible, i.e. CRC cards and whiteboards over round-trip modelling tools.
The simplest answer about the amount of design required is that it depends. It depends on the people on the team (as most issues do), and their level of experience and expertise, their ability to learn and the ways in which they view the world. There are people who can just see the abstractions in a system, where others need to work their way through a modelling exercise. As a result, each team will require different levels of design effort. The one overarching principle, though, is that a team should not design everything up front, and they should validate their designs with tests and code as soon as possible.
There are design decisions, that are perceived as difficult to change once they are made and thus people want to get them right up front. The selection of a programming language or platform (e.g. Java/J2EE, .NET, Ruby/Ruby on Rails/LAMP, etc.), or whether to use a web interface or GUI are examples of fundamental decisions that people believe are hard to change.
However, Martin Fowler makes a powerful argument that these assumptions are to an extent invalid, and indeed lead to more complexity in a system than is required.