Layering partitions the functionality of an application into separate layers that are stacked vertically. In layering, each layer interacts only with the layer directly underneath (Figure 3.2).
Figure 3.2 Layers
It is easy to see that changes can be effected on layer 3 with minimal side effects on layer 1. Moreover, layer 3 could be totally replaced, as long as it met layer 2's contract, without affecting layer 1. This property is known as strict layering.
Critics of strictly layered architectures argue that performance and sometimes extensibility are sacrificed, as more activity is required to propagate down through the layers. Extensibility can suffer if contracts defined between the layers are not robust enough to handle future requirements. However, being able to strategically distribute the application layers, use the domain layer across applications, and easily configure various data sources and user interfaces overcomes these criticisms. Nonstrict layering (Figure 3.3) allows a higher layer to access any layer defined below it and answers the critics' arguments against performance and extensibility; however, it nullifies the benefits of strict layering.
Figure 3.3 Nonstrict Layering