Layered Architecture (Software Architecture)
A Layered Architecture is a design paradigm for creating abstract divisions from related functionality in a software system.
"The layers architectural pattern helps to structure applications that can be decomposed into groups of subtasks in which each group of subtasks is at a particular level of abstraction." [📖POSA, p. 31]
A Layered Architecture may consist of
- Client Layer
- Application Layer
- Domain Layer
- Infrastructure Layer
The interaction of a client with the depicted architecture starts at the top: The commands of the client are passed to the Application Layer and processed by the layers beneath it. In this model of hierarchical layers, a layer is only aware of the layer(s) beneath it. This model follows [📖DDD, pp. 68-71].
How layers relate to each other
Lower layers know nothing about the upper layers: An Infrastructure Layer that is aware of the Application Layer is considered bad design as it violates the SRP and the DIP.
But should the Application Layer know that there is an Infrastructure Layer? Purists might say no, more Pragmatic Programmers probably consider a maybe.
In regard to a likely interdependency of the Presentation Layer and the Data Layer, Fowler et al. write:
"Sometimes the layers are arranged so that the domain layer completely hides the data source from the presentation. More often, however, the presentation accesses the data store directly. [...] The presentation may interpret a command from the user, use the data source to pull the relevant data out of the database, and then let the domain logic manipulate the data [...]." [📖POEAA, p. 20]
Wiring all communication from upper layers through each layer to the target layer may result in Needless Complexity. The DIP provides a solution for setting up communication contracts between upper layers towards lower layers without the need to iterate through all layers available:
"The lower level modules provide the implementation for interfaces that are declared within, and called by, the upper level modules." [📖ASD, p. 129]
But even if we agree that upper layers may be aware of lower layers, and lower layers have no knowledge about upper layers, we still must make sure that communication works in both directions. This is of particular importance when asynchronous processes are used by the Infrastructure Layer, and where the Domain or Application Layer are depending on the results of these processes:
"Layers are meant to be loosely coupled, with design dependencies in only one direction. [...] but when an object of a lower level needs to communicate upward, we need another mechanism, drawing on architectural patterns for relating layers such as callbacks and OBSERVERS ([📖GOF])." [📖DDD, pp. 72-73]
"Layer" vs "Tier"
A Layered Architecture makes no predication about the technology used, and whether other layers are hosted next to layers of a different context. Is a Multitier Architecture more consistent in this regard?
We use the term Layer as an abstract representation of logical tasks grouped together. A Layer could easily be represented by modules and packages, using namespaces to delineating its responsibilities and to provide a semantic context.
The consensus seems to be that a Multitier Architecture implies the physical separation of its tiers. It is often referred to as a system where the actors are physically separated: For example, the application tier exists on a dedicated application server, and the data tier is a (compound of) database server(s).
In the 2nd edition of Core J2EE Patterns, the authors refer to tier as "A tier is a logical partition of separation of concerns in the system." [📖J2EE, p. 120] and further elaborate "We view each tier as logically separated from one another.".
Conversely, the authors of the IBM website take the position that
"They [tier and layer] aren't the same. A 'layer' refers to a functional division of the software, but a 'tier' refers to a functional division of the software that runs on infrastructure separate from the other divisions." [https://www.ibm.com/topics/three-tier-architecture, 14.03.2023, 22:01]
There is no formal definition of the two terms. When in doubt, agree on a definition in your team so that the correct meaning becomes part of your project's Ubiquitous Language.