In order to achieve useful outcomes software must comprise a variety of behaviours. These behaviours can be grouped into particular areas of concern. In developing line of business applications (and generally across a number of application types) there are three common areas of concern; presentation, business logic and persistence. Presentation concerns the display of information to the end user and the handling of user input. Business logic is concerned with the handling of the business functionality for which the application is constructed. Persistence concerns the storage and retrieval of the data on which the application operates. Applications may have other concerns as dictated by their requirements and certain classes of applications will not contain one or more of these concerns (for instances services often do not have a user interface and thus are not themselves concerned with presentation). Concerns may be identified as having a high level of cohesion in their purpose.

It is considered best practice in building an application to have separation of concerns. This implies that each concern is, to the extent feasible, independent of each other and capable of being modified or replaced without impacting the other concerns. This implies that there should be low coupling between concerns. Implementing separation of concerns provides a number of advantages to your application architecture.

One of the most important benefits of separating concerns is that it allows the logic of the concerns to be consolidated. This significantly reduces duplicate implementation. In addition to reducing the direct cost of implementation the more significant benefits come from improved maintainability and reduced risk of errors. Having a single implementation of logic ensures that the logic is consistent in all places it is used. Duplication introduces significant risks that the logic will not be consistently applied to begin with. It runs a larger risk that during maintenance the logic will not be updated consistently in all places resulting in inconsistent behaviour within the application. Such bugs can be difficult to detect and resolve. Additionally if an application implements multiple variants of a behaviour it may not be easy to determine which variant (if any) if the correct behaviour. These risks are intensified where the logic is tightly coupled with other concerns and has been varied with each usage. This can make even identifying that the logic is present difficult to determine.

By separating concerns it is possible to reuse the implementation of a concern in multiple contexts without modification. This may allow for instance the presentation layer of an application to be swapped out so that the business logic and persistence implementation may be shared between a web front end and GUI client. Another possible example is an application where the persistence layer may be replaced in order to communicate with different DBMSes such as Microsoft SQL Server or Oracle. By keeping as much of the application the same as possible the cost of maintenance is significantly reduced. Possibly more importantly we ensure that the application behaves identically in all areas not specifically related to the point of difference, ensuring greater consistency and higher compatibility.

Testability is also enhanced by utilising a separation of concerns. Apart from the obvious benefit of reduced duplication leading to less code to be tested being able to separate concerns allows tests to focus specifically on the logic under test. Concerns not under test may be replaced by mocks or stubs which significantly reduces the scope the test is required to cover. For example having a separate persistence concern can allow logic to be tested without requiring an actual database to test against. Testing against a database is complicated and error prone as the tests need to ensure that the database is in a known, consistent state before each test which can be difficult to establish. Mocking the persistence layer allows the required behaviour to be simulated in a much simpler fashion and allows the behaviour to be varied between each test in a more controlled fashion.

Separation of concerns is commonly provided by using layers which define the boundary for the implementation of the concern. Communication between layers is through defined interfaces that are provided by layers that contain logic required by other layers. These interfaces abstract away the implementation specifics of the layer allowing client layers to be isolated from implementation details. Layers are typically arranged in a stack where each layer exposes an interface to the layer above and communicates with the layer below via the interface the lower layer exposes. Generally in this arrangement the architecture mandates that each layer may only talk to the layer directly below it and not to layers further down. To do so violates the abstraction of the layer below by exposing knowledge of what sits underneath it. This means that the layer is not a complete abstraction.

A system with persistence, business logic and persistence layers is commonly known as a 3-tier architecture (or n-tier in some usages). Although this should technically be used to refer to systems where the elements reside on different tiers in the host environment use to describe a layered architecture of this form is common (if not entirely accurate) in cases where all layers reside on the same machine or in the same process.