Layered Architecture
Layered Architecture is an idea where you have separate layers dealing with different concerns in your application. You can visualise this like a wedding cake, where the layers on top depend on the layers below. The lower layers can not depend upwards. This prevents cyclic dependencies.
Here is an example of a layered architecture
UI Layer: This contains our user facing interface, all the presentation code
Domain Layer: This contains our business objects and logic
Infrastructure/Data Layer: This does some kind of input/output for our application like talking to an external payment system or a database
This is just a conventional example of a layered architecture, but you can use any kind of layers that make sense for your application.
The code is usually organised or tied together using facades. Meaning we provide some public services which can be consumed by other layers, so they don't need to care about the complexity or the implementation of the other layers.
So for example, the UI layer could talk to an OrdersService in the domain layer, which then talks to a repository which talks to the database.
Advantages
This gives you separation of concerns, so you can substitute layers with alternative implementations, if you are using this facade pattern then you can for example, replace your framework for talking to your database without interrupting your other code.
You can defer decisions about your implementations of other layers, so for example in a new application, you can create your domain model using TDD before having to worry about implementation of other layers.
Minimise dependencies, meaning the amount of times you interact with other layers is lowered. This is important to avoid what is called Coupling.
Coupling - My component knows how your component works, so one module is forced to change because another does.
By having layers we introduce cohesion, which means that things that change together live together and otherwise they are apart. For example, if the payment provider changes then the domain shouldn't change.
If you don’t use layering, changes become very hard because you have to change a lot of the code and it becomes difficult to reason about.
Layering is a tool to give you low coupling and high cohesion.