about software programming techniques


JJ van Zon 2023

🧅 Layers

back

Software can be built up of layers. This article describes how layers could be structured. Each layer comes with different technology.

Contents

3 Layers

Software can be split up into 3 main layers:

The presentation layer is the visual part of a program. It is what the user sees.

The business layer is like internal, mechanical parts. It can model the functionality of a program, but it isn’t directly visible.

The data layer stores the data. It models functionality more passively: It does not really process anything. It just stores things.

Connections Between Layers

The presentation layer builds upon the business layer with user interface technology.

The business layer uses the data layer to store the data.

Skipping Business Layer

Sometimes the presentation layer skips the business layer using the data layer directly, represented with the dotted line in the diagram above. This can happen when the business layer does not really add any functionality.

Patterns

The data layer may be programmed with mostly fixed patterns in this architecture. The presentation layer is mostly patterns too. The business layer can have patterns as well, but it gets a little more creative. If anything special needs to happen, it might be put in the business layer.

Data Layer

The data layer models and stores the data. It might be built up of the following sub-layers:

Database (DB)

It starts with the database. This can be a relational database like Microsoft SQL Server, which structuredly stores the data into tables and relationships. But it could also be another type of data store: an XML file, flat file or even just in-memory data.

ORM (NHibernate)

The database might not be directly accessed by the rest of the code. It may go through an object-relational mapper (or ORM), like NHibernate. This ORM would translate database records to objects called entities.

It could also be a different data access technology: a different ORM, like Entity Framework, or XML files, or perhaps SqlClient to execute raw SQL onto the database.

Mappings

Entity objects have properties, that map to columns in the database, and properties that point to related entities. NHibernate needs mappings, that define which class maps to which table and which column map to which property.

The FluentNHibernate API can help set up these mappings.

Entities

With all this in place, out come objects called entities, loaded from the database. These entity objects represent the functional domain.

Repositories

NHibernate might not be directly accessed by the rest of the code. The other code might talk to the Repositories instead. You might see a Repository as a set of queries. Each entity type could have its own Repository. Next to providing a central place to manage an optimal set of queries, the Repositories keep the rest of the code independent of NHibernate, in case you would like to switch to a different data technology.

Repository Interfaces

The Repository implementations might not used directly, but accessed through interfaces, so that we can indeed use a different data access technology, just by instantiating a different Repository implementation.

Platform Independence

The dashed line going right through the diagram above, separates the platform-specific part from the platform independent part.

The platform-specific part concerns itself with NHibernate and SQL Server. The platform independent part is unaware of the underlying storage technology. You may as well stick an XML file under it and not use SQL Server or NHibernate at all.

This makes it possible, to program against the same model, regardless of how it is stored. This platform-independence, also helps deploy the same code to different environments like mobile, Windows or web.

Presentation Layer

The presentation layer is the visual part of a program. It is what the user sees. It can be split up into the following sub-layers:

Calls the Business Layer

The presentation layer calls the business layer, which contains the rules that surround the system. It feeds the business layer input from the user, and processes the output data for display on screen.

Presenter

It is the Presenter classes that talk to this business layer. The Presenters together form a model of application navigation. Each screen might get its own Presenter. Each Presenter method represents a specific user action on that screen.

ViewModel

A ViewModel would contain a specific subset of data: exactly the selection of data, that is shown on screen. In this architecture ViewModels are a pure data objects, no logic. So they can be more easily used with different presentation technologies. These pure data objects can also be sent over the line without many surprises.

ToViewModel

The Presenters might delegate to a ToViewModel layer, to translate the data and the results from the business logic to a subset of data that is shown on screen.

ToEntity

The Presenters also delegate to a ToEntity layer, to translate user input back to entity data, before passing it on to the business layer.

Facades

Presenter classes combine several responsibilities around presentation.

They call upon the business layer to Save, Validate, execute SideEffects. They initiate translation between entities and ViewModels and might also execute security checks.

Because the Presenters combine several responsibilities together, they can be called the Facades or combinators of the presentation layer.

MVC

MVC is the technology of choice in this architecture for programming user interfaces for web technology. In this architecture the MVC layer builds on top of the Presenter layer.

MVC Controllers

MVC uses Controllers, which are similar to Presenters in that they group together related user actions and each user action gets a specific method.

Controllers are quite specific to MVC. An equivalent might not be present on other presentation platforms.

However, even on other presentation platforms, like WinForms, it might be advisable, to have a central spot to manage calls to the Presenters and showing the right View depending on their results.

URLs

Requests from the web browser automatically make the right Controller method go off. MVC makes sure of that. Each method in a Controller tends to get a URL.

The parameters of a Controller method can be URL parameters. A parameter can also be post data. ViewModel parameters are accepted by MVC Controllers. The ViewModels and are built up from post data by MVC automatically.

JJ.Framework.Mvc might be used to send whole tree structures of post data over the wire to be correctly parsed by MVC.

View Engine (Razor)

After the Controller method is done, the view engine kicks in. The view rendering automatically goes off.

Views (Razor)

A view engine that might be used in this architecture is Razor. It offers a concise syntax for programming Views, that combines C# with HTML. Razor has tight integration with MVC. The view engine can use a ViewModel as input, along with the View template (*.cshtml). The output is a specific piece of HTML sent back to the web browser.

In WinForms the Views would be the Forms and UserControls. It is advisable that even if a View can have code-behind, to only put simple code in it and delegate the real work to Presenters.

HTML

The Razor engine produces a piece of HTML received by the web browser.

HTML here can be replaced by the type of presentation output. In WinForms it might be the controls and their data. But it can also be a generated PDF file. Anything that can come out of a presentation technology might be considered a View.

Platform Independence

The dashed line going right through the diagram above separates the platform-specific part from the platform independent part.

The platform-specific part concerns itself with MVC, HTML and Razor, while the platform independent part is unaware of which presentation technology is used.

That means that we can use similar logic for multiple presentation techniques, such as offering an application both web based as well as Windows or a mobile app.

Business Layer

What is business logic? Basically anything that is not presentation, data access or infrastructure, might be considered the business logic. It’s the rules of a system. It’s like the internal, mechanical parts. The business layer might be split up into the following things:

Layer Connections

The business layer resides in between the data access and the presentation layer.

The business layer can use entities out of the data layer. These entity classes represent the domain model. But sometimes it would call repositories to execute queries.

Magic

The presentation layer uses the business layer for anything special that might be done. The business layer guards rules and such. Sometimes when something special is programmed in the presentation layer, it may be worth considering moving it to the business layer.

Validation

The business layer can execute Validators that verify that the data corresponds to expectations.

SideEffects

The business layer can execute SideEffects when altering data, for instance updating the date time modified or automatically generating a name for a new object.

Calculations

The business layer would also be responsible for calculations.

Conversions

One thing can be converted to another. Conversions might be found in the business layer. This could be for simple objects. But you might also convert whole trees and structures to another.

Enums

Enums are like multiple choice variables. Some entities in the data layer might have corresponding enums in the business layer. And some pattern-wise logic around enums might be there in the business layer too.

Resources Strings

Resource strings can make texts in an app multi-lingual. These might be put in the business layer to translate terminology from the functional domain.

Defaults

Setting default values when creating an entity might be done automatically by using a SideEffect class. Those may be executed in the business layer.

Cascading

Along with one entity, other entities might be deleted. Cascading here means the deletion of related entities when a main entity is deleted. Cascading can also mean unlinking some entities before deleting a related entity. In this architecture this might be done in C# to make it extra visible that these deletions take place.

Cloning

Sometimes there is code for cloning or copying an object or graph of objects. Code for this kind of cloning might be put in the business layer too.

Bidirectional Relationship Synchronization

Bidirectional relationship synchronization can keep the two ends of a relationship in sync. By setting the parent property, product.Supplier = mySupplier, the child collection, mySupplier.Products, will also be updated to include myProduct. This mechanism can be made part of a business layer.

Facades

Calling the business layer can happen through Facades. They would combine several aspects of the business logic, by calling Validators, SideEffects, Cascading and other things in all a row. Facades might provide a few main entry points into the business layer.

CRUD

The Facades may orient around the basic data operations: Create, Read, Update and Delete or CRUD. This set of basic operations might not change much, keeping the interfaces relative stable. But Non-CRUD operations might be added too.

Platform Independence

A business layer might be platform independent in this architecture, so that the code can be used anywhere. When most things are built upon entities and repository interfaces, the business logic is relatively independent, which means that the magic of the software would be deployable on many platforms. Sometimes this might require specific API choices, generic interfaces and in-house programmed API's. These choices are inherently part of this software architecture.

Perpendicular Layers

The subdivision into data, business and presentation is quite fundamental in this software architecture. But there can also be additional layers, called perpendicular layers:

Perpendicular

At the bottom you can see Data, Business and Presentation layers, laid down flat on their side. The perpendicular layers are rotated 90° and placed right on top of the main layering. That’s why these layers are called perpendicular.

Framework

The Framework layer consists of API's that could support any aspect of software development, so could be used in any part of the layering. That is why it stretches right from Data to Presentation in the diagram.

Infrastructure

Infrastructure is things like security, network connections and storage.

The infrastructure can be seen as part at the outer end of the data layer and part at the outer end of the presentation layer, because the outer end of the data layer is actually performing the reading and writing from specific data source.

However it is the presentation layer in which the final decision is made what the infrastructural context will be. The rest of the code tends to operates independent of the infrastructure in this architecture and only the top-level project would eventually determine what the context will be.

Loosely Coupled

The infrastructure tends to be loosely coupled in this software architecture. Let’s take user rights management an example.

User rights management can alter the program navigation model in the Presenter layer, adapting it to what the user is allowed to do.

In that respect the platform-independent presentation layer is dependent on the security infrastructure, which is a paradox. The reason the Presenter layer is platform-independent after all, is that it communicates with the infrastructure using an interface, that may have a different implementation depending on the infrastructural context in which it runs. This could be accomplished with a config file or dependency injection.

Services

What’s meant with services in this architecture, is exposing business logic through a network interface, like the SOAP protocol. A service may also expose a presentation model to the outside world.

Decoupled

Presenter classes decouple presentation from business logic so you have full flexibility in the presentation layer. Presenters also decouple the presentation technology so it can be flexibly replaced. The repositories decouple the data technology. And the generic interfaces on infrastructure decouple the infrastructure. Everything is decoupled to keep our options open.

Alternatives

Here is a variation on this architectural layering, that might also sometimes be used: data and business in one layer. Benefit: Might be easier to understand. Downside: More likely for data access and business to get entangled.

Another alternative is: no repositories. But C# interfaces for everything. Not bothering with what’s data or business or repository.

It would still keep things loosely coupled and separation of concerns would also stay intact.

back