Layered (N-Layer) Architecture

--

In this article, we are going to talk about Layered (N-Layer) Architecture for application designs where and why we use this architecture on our applications. We will touch Benefits and Challenges of this architecture. After that we will design Layered architecture on e-commerce domain.

By the end of the article, you will learn where and when to apply Layered Architecture with designing e-commerce application system with applying KISS, YAGNI, SoC and SOLID principles.

Step by Step Design Architectures w/ Course

I have just published a new course — Design Microservices Architecture with Patterns & Principles.

In this course, we’re going to learn how to Design Microservices Architecture with using Design Patterns, Principles and the Best Practices. We will start with designing Monolithic to Event-Driven Microservices step by step and together using the right architecture design patterns and techniques.

What is N-Layer architecture ?

Basically, N-layer application is partition application logic into specific layers. The N-layer architecture pattern is a mature architecture and simply refers to applications separate various logical layers into separate physical tiers.

The most common layers include:

• User interface
• Business logic
• Data access

We can say these layers as a

A presentation tier, for example a web app.
An Business tier, including use case implementations and expose them such as a REST API.
A data tier, such as a SQL database.

Other layers may include middleware, batch processing, and API. It’s important to note the layers are logical. Although they’re developed in isolation, they may all be deployed to the same target platform.

After learning the basics of N-Layer architecture, we should also understand the principles that we will apply on our architecture afterwards.

Design principles — Separation of Concerns (SoC)

Think about that what is the motivation the use N-Layer architecture ? Why we separate the layers to N ? What is the underlying principle to create this N-Layer architecture.

This principle is Separation of Concerns (SoC).

SoC says that the elements in the software should be unique to them,
not to share their responsibilities with other staff members. While developing the software, we can see the necessary of separating responsibilities with following this principle.

We can say that, we distinguish between the concepts of layer and tiers with certain responsibilities. If we go further a little more, the namespaces of our software components can also be used as limits to allocate responsibilities.

The dependencies of the components within the software and
the cohesion within the components are two important concepts for the SoC principle. It should always be preferred that the dependency of the components is low and that the relationship of responsibility in a component is high.

So low-coupling, high-cohesion is indispensable. If the dependency of commitment is low, then the control of the software will be easier in our hand, since the liability will be distributed per component. Being close to each other in their responsibilities within the components will becomes re-usability.
We can give an example of SoC that development of Web UI. As you can see that UI element i.e. button needs to configure by 3 structure; HTML — CSS — JS.

Design principles — SOLID

SOLID is one of the main principle groups to use almost every software projects.

This one though, stands for:

  • Single Responsibility Principle
  • Open-Closed Principle
  • Liskov Substitution Principle
  • Interface Segregation Principle
  • Dependency Inversion Principle

So if you think about it, it’s really 5 principles all packed into one.
So let’s unpack them one by one.

Single Responsibility

The idea is that each of your classes (or modules, units of code, functions, etc) should responsible only one functionality. Why ?

Because if you want to change your code, you should first have a good reason, then you should know where is that single point where that reason applies. We can use this base principles when designing the system also.

Open-Closed Principle

When you write your code, the last thing you want to do is go back to it and change it again and again whenever you implement a new functionality. You want the legacy code to work, be tested to work, and allow new functionality to be built on top of it.

In the same way, when we design the system, it should able to extend without changing existing architecture. For example using pub/sub pattern with message brokers is a good example for that. If we want to notify some other microservices, instead of calling their services, we can publish an event and they can consume them from message broker.
By this way, if there will be a new microservice need to consume this event, we don’t change anything for existing architecture, the only thing to subscribe that event from message broker that’s all. So our design open for extensions and close for modifications.

Liskov Substitution Principle

I am not going to give deep explanation about that. Because we are looking this principles from the system design perspective. So we can say that, our systems can be substitute each other easily.
In our case we can use plug-in services that we can shift them easily, For example if we use RabbitMQ as a message broker, we can shift to Kafka easily with abstracting Event Bus implementations.

Interface segregation principle

It basically says split your interfaces — meaning the desired functionality of your code — into pieces that are fully used.

Dependency Inversion Principle

Also known as dependency injection. If you have dependencies in your code, you should allow for them to be injected into your logic.
How do you do that ? Of course By allowing them to be passed in as parameters.

This is a very useful principle that we can use system architecture design.
We don’t want to dependent microservices and direct communication due to possible network problems. In order to broke this dependencies, we can use message brokers and event-driven architecture that provide to de-couple services.

As you can see that we understand SOLID principles and how we can use them when architecting system designs.

Design the Architecture — E-Commerce App — Layered Architecture

We are going to Design the architecture according to new learnings with principles and Layered Architecture.

You can find latest design here, and we will evolve our monolithic architecture to layered architecture with following newly learning principles.

As you can see that, we separated the UI and the Business Logic concerns in layered architecture.

Technology choices — Adapting Technology Stack

We are going to Adapting Technology Stack, implement possible Technology choices.

As you can see that we have design our e -commerce application as a Layered architecture and handle to FR and NFR requirements like scalability, reliability and so on.
But our business is still growing and current architecture can’t respond the business requirements and also client request of our application.
So we need to consider new architectures.

In order to increase concurrent request we should evolve our architecture to Microservices Architecture.

Step by Step Design Architectures w/ Course

I have just published a new course — Design Microservices Architecture with Patterns & Principles.

In this course, we’re going to learn how to Design Microservices Architecture with using Design Patterns, Principles and the Best Practices. We will start with designing Monolithic to Event-Driven Microservices step by step and together using the right architecture design patterns and techniques.

--

--

Mehmet Ozkaya
Design Microservices Architecture with Patterns & Principles

Software Architect | Udemy Instructor | AWS Community Builder | Cloud-Native and Serverless Event-driven Microservices https://github.com/mehmetozkaya