Clean Architecture - An Introduction

avatar

What is N-Tier Architecture?

User interface layer, business logic layer, introducing clean architecture, domain layer, application layer, infrastructure layer, presentation layer, testing layer, starter templates.

For a long time, I have been using the classic "N-Tier" architecture (UI Layer -> Logic Layer -> Data Layer) in most of the applications I build. I rely heavily on interfaces, and learnt a long time ago that IoC (Inversion of Control) is your friend. This architecture enabled me to build loosely coupled, testable applications, and has served me well so far. However, like many professional software engineers, I'm always on the look out as to how I can improve my architecture when designing applications.

Recently, I came across Clean Architecture from a presentation by Jason Taylor at a Goto conference, and have become fascinated with this architecture / pattern. It validated some of the things I had already been doing, but improved in other areas that always felt a bit clunky to me (like integrating with 3rd party services, and where the heck does validation go?).

NOTE: Although this architecture is language and framework agnostic, I will be mentioning some .NET Framework terms to help illustrate concepts.

First off, let's examine the classic N-Tier architecture. This has been around for 20+ years, and it still common in the industry today.

N-Tier most commonly has 3 layers:

N-Tier Architecture

Each layer is only allowed to communicate with the next layer down (i.e UI cannot communicate directly with Data). On the surface this limitation might seem like a good idea, but in implementation, it means a different set of models for each layer which results in way too much mapping code. This problem gets amplified the more layers you add.

  • Controllers
  • Static Assets

Typically this would be an MVC or Web API project.

  • Business / Application Logic (usually implemented as Services)
  • Integration with 3rd party services
  • Calls directly into the Data layer

This is where the meat of an N-Tier application is.

  • Data models
  • Database access

This architecture has had many names over the years. Onion Architecture , Hexagonal Archecture , Screaming Architecture , and others. This approach is not new, but it is also not nearly as common as it perhaps should be.

So, compared to N-Tier, what is Clean Architecture and how is it different?

Let's start with a picture:

Clean Architecture

The first thing to notice here is the direction of the dependencies. All dependencies flow inwards. Outer layers can communicate with ANY inner layer (compare this to N-Tier where each layer can only communicate with the one below it). This follows the Dependency Inversion Principle which means that dependencies are injected instead of being explicitly created. Another name for this is the Hollywood Principle: Don't call us, we'll call you . 😊

Application and Domain are considered the 'core' of the application. Application depends on Domain , but Domain depends on nothing.

When the Application needs functionality from Infrastructure (e.g. database access) the application will define it's own interfaces that infrastructure will implement. This decoupling is huge, and is one of the major benefits of this approach. Not only does it allow for easier unit testing, it also means it is persistence ignorant. When querying data, the underling data store could be a database, web service, or even flat file. The application doesn't care and doesn't need to know. With the implementation details being outside core, it allows us to focus on business logic and avoids pollution with less important details. It also provides flexibility in that today the data might come from one data source, but in the future it may need to come from a different data source. Due to the loose coupling, only the infrastructure layer will need to change to support this.

Jeffrey Palermo defined Four Tenants of Clean Architecture:

  • The application is built around an independent object model
  • Inner layers define interfaces. Outer layers implement interfaces
  • The direction of coupling is toward the center
  • All application core code can be compiled and run separate from infrastructure

All of this strives to make it easy for developers to do the right things, and hard for them to do the wrong things. We are striving to "force developers into the pit of success".

  • Value Objects
  • Aggregates (if doing DDD)
  • Enumerations

The Domain Layer is the heart of your application, and responsible for your core models. Models should be persistence ignorant, and encapsulate logic where possible. We want to avoid ending up with Anemic Models (i.e. models that are only collections of properties).

The Domain Layer could be included in the Application Layer , but if you are using an ORM like entity framework, the Infrastructure Layer will need to reference the domain models, in which case it's better to split out into a separate layer.

Data annotations should be left out of domain models. This should be added in the Infrastructure Layer using fluent syntax. If you are used to using the data annotations for you validation, I instead recommend using Fluent Validation in the Application Layer , which provides event more capability than annotations.

  • Application Interfaces
  • View Models / DTOs
  • Application Exceptions
  • Commands / Queries (if doing CQRS)

This is the Application of your Domain use to implement the use cases for your business. This provides the mapping from your domain models to one or more view models or DTOs.

Validation also goes into this layer. It could be argued that Validation goes into the domain, but the risk there is that errors raised may reference fields not present in the DTO / View Model which would cause confusion. IMO it's better to have potentially duplicated validation, than it is to validate an object that has not been passed into the command/query.

My preference is to use CQRS Commands and Queries to handle all application requests. MediatR can be used to facilitate this and add additional behaviour like logging, caching, automatic validation, and performance monitoring to every request. If you choose not to use CQRS, you can swap this out for using services instead.

The Application Layer ONLY references the Domain Layer . It knows nothing of databases, web services, etc. It does however define interfaces (e.g. IContactRepository, IContactWebService, IMessageBus), that are implemented by the Infrastructure Layer .

  • Web services
  • Message Bus
  • Configuration

The Infrastructure Layer will implement interfaces from the Application Layer to provide functionality to access external systems. These will be hooked up by the IoC container, usually in the Presentation Layer .

The Presentation Layer will usually have a reference to the Infrastructure Layer , but only to register the dependencies with the IoC container. This can be avoided with IoC containers like Autofac with the use of Registries and assembly scanning.

  • MVC Controllers
  • Web API Controllers
  • Swagger / NSwag
  • Authentication / Authorisation

The Presentation Layer is the entry point to the system from the user's point of view. Its primary concerns are routing requests to the Application Layer and registering all dependencies in the IoC container. Autofac is my favourite container, but use whatever makes you happy. If you are using ASP.NET, actions in controllers should be very thin, and mostly will simply passing the request or command to MediatR .

The Testing Layer is another entry point to the system. Primarily this should be aiming at the Application Layer , which is the core of the application. Because all infrastructure is abstracted by interfaces, mocking out these dependencies becomes trivial.

If you are interested in learning more about testing I highly recommend Clean Testing .

The layers described so far, make up the basic approach of Clean Architecture. You may need more layers depending on your application.

If you are not using an ORM you may be able to combine Domain and Application Layers for simplicity.

The outer-most right might also have more segments. For example, you may wish to split out infrastructure into other projects (e.g. Persistence).

This approach works well with Domain-Driven Design, but works equally well without it.

CQRS is the recommended approach for the entry point into the Application Layer . However, you could also use typical services if you're not comfortable with that.

I've also seen implementations where the application core is divided up into 4 internal layers. IMO this is overkill for most projects. We want to balance clarity with simplicity.

This all sounds great right? But how can I get started?

Fortunately for us all Jason Taylor has created a .NET Core Solution Template, that contains a fully functioning application with an Angular 9 Frontend, and associated unit and integration tests. This is a great starting point to see everything in action.

Clean Architecture Solution Template

You can find more about this here

Clean Architecture is by no means new, and is nothing groundbreaking. However, with a few tweaks on the typical N-Tier architecture the result is a completely testable, more maintainable solution that can adapt to change faster. Due to the loose coupling between outer and inner layers, modifications can be made easier, which can be the difference between an application lasting 2 years and 10 years.

I'm still working out the kinks in my own implementations, but really see the advantages with this approach and am excited to see the results over time.

Give it a try and let me know how you go.

  • Clean Architecture - Jason Taylor
  • Rules to Better Clean Architecture
  • Microsoft Docs - Clean Architecture
  • The Clean Architecture - Robert C. Martin
  • Peeling Back the Onion Architecture - Tony Sneed
  • Onion Architecture - Jeffrey Palermo

Flutter App Architecture: The Domain Model

Andrea Bizzotto

Andrea Bizzotto

Feb 9, 2022 9 min read

Have you ever mixed up your UI , business logic and networking code into one messy bundle of spaghetti code?

I know I did. ✋

After all, real-world app development is hard.

Books such as Domain-Driven Design (DDD) have been written to help us develop complex software projects.

And at the heart of DDD lies the model , which captures important knowledge and concepts that are needed to solve the problem at hand. And having a good domain model can make all the difference between the success or failure of a software project.

Models are very important but they cannot live in isolation. Even the simplest of apps requires some UI (what the user sees and interacts with) and needs to communicate with external APIs to show some meaningful information.

Flutter Layered Architecture

In this context, it's often valuable to adopt a layered architecture, introducing a clear separation of concerns between different parts of the system. And this makes our code easier to read , maintain and test .

Broadly speaking, four different layers are normally identified:

  • presentation layer
  • application layer
  • domain layer

The data layer sits at the bottom and contains the repositories that are used to talk to external data sources.

Just above it, we find the domain and application layers. These layers are very important as they hold all the models and business logic of our app. For more info, read the other articles in this series:

  • Flutter App Architecture with Riverpod: An Introduction
  • Flutter Project Structure: Feature-first or Layer-first?
  • Flutter App Architecture: The Repository Pattern
  • Flutter App Architecture: The Presentation Layer
  • Flutter App Architecture: The Application Layer

In this article, we'll focus on the domain layer , using an eCommerce application as a practical example. As part of this, we will learn:

  • what is a domain model
  • how to define entities and represent them as data classes in Dart
  • how to add business logic to our model classes
  • how to write unit tests for that business logic

Ready? Let's go!

What is a Domain Model?

Wikipedia defines the domain model like this:

The domain model is a conceptual model of the domain that incorporates both behavior and data .

The data can be represented by a set of entities along with their relationships , while the behavior is encoded by some business logic for manipulating those entities.

Using an eCommerce application as an example, we could identify the following entities:

  • User : ID and email
  • Product : ID, image URL, title, price, available quantity etc.
  • Item : Product ID and quantity
  • Cart : List of items, total
  • Order : List of items, price paid, status, paymente details etc.
When practicing DDD, entities and relationships are not something we produce out of thin air, but rather the end result of a (sometimes long) knowledge discovery process. As part of the process, a domain vocabulary is also formalized and used by all parties.

Note how at this stage we are not concerned about where these entities come from or how they are passed around in the system.

What's important is that our entities are at the heart of our system, because we need them to solve domain-related problems for our users.

In DDD, a distinction is often made between entities and value objects . For more info, see this thread about Value vs Entity objects on StackOverflow .

Of course, once we start building our app we need to implement those entities and decide where they fit within our architecture.

And this is where the domain layer comes in.

Going forward, we will refer to entities as models that can be implemented as simple classes in Dart.

The Domain Layer

Let's revisit our architecture diagram:

As we can see, the models belong to the domain layer. They are retrieved by the repositories in the data layer below, and can be modified by the services in the application layer above.

So how do these models look like in Dart?

Well, let's consider a Product model class for example:

At a very minimum, this class holds all the properties that we need to show in the UI:

And it also contains fromMap() and toMap() methods that are used for serialization.

There are various ways to define model classes and their serialization logic in Dart. For more info, see my essential guide to JSON parsing in Dart and the follow up article about code generation using Freezed .

Note how the Product model is a simple data classes that doesn't have access to repositories, services, or other objects that belong outside the domain layer.

Business logic in the Model classes

Model classes can however include some business logic to express how they are meant to be modified.

To illustrate this, let's consider a Cart model class instead:

This is implemented as a map of key-value pairs representing the product IDs and quantities of the items that we have added to the shopping cart.

And since we can add and remove items from the cart, it may be useful to define an extension that makes this task easier:

The methods above make a copy of the items in the cart (using Map.from() ), modify the values inside, and return a new immutable Cart object that can be used to update the underlying data store (via the corresponding repository).

If you're not familiar with the syntax above, read: How to update a Map of key-value pairs in Dart .
Many state management solutions rely on immutable objects in order to propagate state changes and ensure that our widgets rebuild only when they should. The rule is that when we need to mutate state in our models, we should do so by making a new, immutable copy .

Testing the Business Logic inside our Models

Note how the Cart class and its MutableCart extension don't have dependencies to any objects that live outside the domain layer.

This makes them very easy to test.

To prove this point, here's a set of unit tests that we can write to verify the logic in the addItem() method:

Writing unit tests for our business logic is not only easy, but adds a lot of value .

If our business logic is incorrect, we are guaranteed to have bugs in our app. So we have every incentive to make it easy to test, by ensuring our model classes don't have any dependencies.

We have discussed the importance of having a good mental model of our system.

We've also seen how to represent our models/entities as immutable data classes in Dart, along with any business logic we may need to modify them.

And we've seen how to write some simple unit tests for that business logic, without resorting to mocks or any complex test setup.

Here are some tips you may use as you design and build your apps:

  • explore the domain model and figure out what concepts and behaviors you need to represent
  • express those concepts as entities along with their relationships
  • implement the corresponding Dart model classes
  • translate the behaviors into working code (business logic) that operates on those model classes
  • add unit tests to verify the behaviors are implemented correctly

As you do that, think about what data you need to show in the UI and how the user will interact with it.

But don't worry about how things connect together just yet. In fact, it's the job of the services in the application layer to work with the models by mediating between the repositories in the data layer and the controllers in the presentation layer.

And that will be the subject of a future article.

Flutter Foundations Course Now Available

I launched a brand new course that covers Flutter app architecture in great depth, along with other important topics like state management, navigation & routing, testing, and much more:

Flutter Foundations Course

Flutter Foundations Course

Learn about State Management, App Architecture, Navigation, Testing, and much more by building a Flutter eCommerce app on iOS, Android, and web.

Invest in yourself with my high-quality Flutter courses.

Flutter & Firebase Masterclass

Flutter & Firebase Masterclass

Learn about Firebase Auth, Cloud Firestore, Cloud Functions, Stripe payments, and much more by building a full-stack eCommerce app with Flutter & Firebase.

The Complete Dart Developer Guide

The Complete Dart Developer Guide

Learn Dart Programming in depth. Includes: basic to advanced topics, exercises, and projects. Fully updated to Dart 2.15.

Flutter Animations Masterclass

Flutter Animations Masterclass

Master Flutter animations and build a completely custom habit tracking application.

Software Alchemy

The Art and Science of Software Development

To ensure you get the best experience, this website uses cookies.

A Template for Clean Domain-Driven Design Architecture

  •   Posted in:
  • Foundational Concepts
  • Architecture
  • Design Patterns
  • Patterns and Practices
  • Domain-Driven Design
  • ASP.NET Core

Architectural Template

The purpose of this blog entry is to introduce an architectural template for building web applications which is based upon my interpretation of the Clean DDD and CQRS concepts that I introduced in the previous entry. The information I provide here is guidance only, and I don't claim this to be the definitive approach to building modern applications. It reflects my own personal software development biases and may or may not be suitable to your needs. Once again, I'm operating under the assumption that you fall into a certain category, namely a developer or team of developers working in a startupy-type environment, or a small team within a larger organization. You embrace Agile and lean startup practices, are flexible in your thinking, and focused on continuous improvement and development. Whatever the case, you should always do your homework as well.

To demonstrate this template, I've created a demo application which attempts to solve a (highly contrived) fictional problem for a fake organization. As indicated in the past few entries, you can find the source code to the demo solution here . Feel free to refer to the source code alongside the architectural guidelines I've outlined below.

In developing this template, I studied solutions and tutorials from a handful of experts. As always, I've linked to those resources at the bottom. The experts/resources that this architecture is based on are Jason Taylor, Julie Lerman, Steve Smith, Jimmy Bogard, Matthew Renze, Vladimir Khorikov, Greg Young, Dino Esposito, and finally the Microsoft e-book, .NET Microservices: Architecture for Containerized .NET Applications.

Out of all of these, I'm most in agreement with the Taylor solution, which in turn seems to be heavily influenced by the Microsoft guide. At first, I wanted to give this template some cool name like "Wolverine Architecture," but I didn't want to come off as too presumptuous, so I will just refer to it as "my architectural template" or "my architecture."

Before I dive in, I'd like to list a few more caveats:

  • The demo application is NOT complete, as it is in an initial state which is sufficient to demonstrate the concepts I've discussed in this and previous blog entries. It will change and evolve over time as I elaborate on more software development topics. As a matter of fact, at this point the actual "app" isn't even an ASP.NET Core web application—I've started it out using a simple console application standing in for the Presentation layer. Hopefully this will help you to get a good idea of how the various layers and their corresponding components communicate through the stack without being distracted by too many boilerplate details that would have been there had I used an actual web app for the main project. I'll try to tag the source code accordingly, so that each revision can be easily indexed to the blog entries that it pertains to.
  • A few key features are currently missing, such as Identity and Security. I'll add those in future posts.
  • This architecture represents the stack up to the Persistence layer. I'm not going to touch on the UI yet.
  • I don't agree with the above references on all points. It's okay to disagree with the experts (although, if you are going to adopt a heretical stance, be well-prepared to defend your choice). I'll try to clarify my reasoning in areas in which I deviate from their approaches.

First, the Use Case

A company would like to have a comprehensive, business-centric application to manage various functions in the organization.

  • They would like to automate processes which belong to the various business units of the organization—Human Resources, Accounting, etc. For example, they need to track payroll at a basic level, and they need a seamless way to onboard or offboard employees through the Manager of HR.
  • They need different adjunct functionalities, like tracking paid time off (PTO) time available, which will be handled through the HR side as well.
  • The business will almost certainly request additional features in the future as the application grows and they have time to interact with it, elucidating more business requirements.

I've been instructed to build an enterprise solution on the .NET Core stack and deploy it to the Azure cloud. Starting out, the system will simply handle basic HR and Accounting, but it MUST be able to grow to accommodate more complex business functions, such as those managed by Operations, or even the executive team themselves. At the outset, I'm only allowed to use a single relational database as the data store, which will also be in the cloud. Additionally, I've been told by the CIO that the Accounting logic will be coded and maintained by a separate team (maybe even a single individual). She tells me this is for political technical reasons. OK, those are my orders. Time to get to work.

A Template for Business-Focused Web Applications in the Microsoft Cloud

Code-level conventions.

As stated in blog entry 4, I generally follow the conventions from Framework Design Guidelines. Once again, I highly, highly recommend that you use a tool like CodeMaid or something similar to automatically clean up and organize your files for you. You can customize it to organize them the way you want. Here are some specifics:

  • Pascal case is used for classes names, method names, properties and so on.
  • Parameter names, private fields, etc. are camel case.
  • Underscores are never used, except in method names for unit tests. I never prefix private fields with underscores.
  • SCREAMING_CASE is never used.
  • While Hungarian notation is not allowed, certain conventions which might resemble it are okay, such as MyCoolController, MyAwesomeVm, UpdateSomethingCommand, etc. In other words, using suffixes. Those are generally okay.
  • I mentioned this in a previous post but here it is again. In recent years there has been a small yet fervent movement to stop prefixing interfaces with "I" because technically it is a vestige of Hungarian notation. DON'T DO THIS. Interfaces should be prefixed with "I" because the distinction between them and other types is so important that their names themselves should express this. If you have any doubts, just look at the source code for the various official Microsoft .NET Core packages. What do they do? (When in doubt, emulate the pros).
  • Fields/constants
  • Properties/indexers
  • Constructors
  • Nested classes

Basic Solution Organization

These are guidelines for organizing the solution into files and projects:

  • There should be one class/enum/interface per source code file. This one drives me nuts. I've encountered solutions in which there are five or six different classes in a single file along with a bunch of enums and other nonsense. However, there is an exception to this rule, which you can see in the demo application: I've nested the handler classes for commands/queries inside the command/query classes themselves. The reason for this is simple, which is that user code doesn't need to call them directly. Remember, we are relying on MediatR to perform the dispatch to handler methods.
  • Project names, folder names, and namespace names should all align. It drives me crazy when I encounter a solution in which there is a folder called "Foo" and the corresponding namespace for classes in that folder is "Bar." Don't do this. Names of everything should align, so that if decide you need to take a folder full of classes and put it into its own project, the namespaces don't break . This idea, which I'll tentatively call the "Project/Folder/Namespace Fungibility principle" is important, because as the solution grows it gives us the flexibility to refactor it easily and move different sections of the architecture into separate microservices. To put it simply, Project Name = Folder Name = Namespace . Do this, and your solutions will be much easier to refactor.
  • Related to the above point is the naming of projects themselves. A good guideline is <Company>.<Solution>.<Layer>.<Bounded context or other detail>. Alternatively, you can use <Solution>.<Layer>.<BC/detail> or whatever. Just be consistent.
  • I recommend keeping your project structure flat (for the most part). This means not hiding projects in some nested folder somewhere, which makes them difficult to find.

External Dependencies

This is a list of third-party toolkits, libraries, and NuGet packages that the solution depends upon. This is not comprehensive, and more will be added as the solution grows over time.

  • MediatR, by Jimmy Bogard - Used in both Domain layer and Application layer. This is a really powerful package and is the special sauce that brings everything together. As stated in the previous entry, MediatR facilitates a simple, elegant CQRS implementation.
  • Entity Framework Core - Microsoft's ORM. Used almost exclusively inside CQRS commands to update the database and sometimes to perform simple queries against it.
  • Dapper - A powerful and efficient micro-ORM which allows us to write flexible queries which translate well into DTO/view models. Used on the query side of the stack to return query results by projecting complex SQL queries into 1NF view models.
  • FluentValidation - Plugs nicely into MediatR and allows for validation of commands that are sent down the stack before they hit the Domain layer.
  • Mapster - A fast and intuitive object mapping library which assists in mapping view models and persistence models to/from domain models. Alternatively, you could use AutoMapper, also by Jimmy Bogard, but at this time I prefer Mapster because it's faster and the usage is slightly more intuitive.
  • Serlilog - A powerful logging library which sits on top of the base .NET Core logging infrastructure.

Logical Organization of the Solution

When working with this or any other architecture, I strive to produce solutions that are neatly organized and easy to navigate. A great principle to follow in this regard is  Screaming Architecture  ( The architecture should scream the intent of the system! ), which is another Uncle Bob-ism. Starting from this, let's discuss for a minute component organization  and  functional organization , which are two distinct methodologies for organizing classes, interfaces, components, and other objects together inside a software solution.

Component Organization

Under component organization, classes, interfaces and other objects are grouped together in folders or projects based upon their category , or what they represent—e.g. Controllers, Views, so on. The underlying concept here is  categorical cohesion , which simply means that entities of the same classification or category should go together. Imagine grouping baseball players from a baseball league. In this way, all third basemen from all teams would go together into one group, pitchers in another, and so on.

This is the default for most solutions in .NET, especially MVC solutions. At first, this seems easier to grasp but has its drawbacks. As the solution grows, you may find yourself "jumping around" more to find dependencies for different components. I've certainly found this to be the case with most legacy systems I've worked on in corporate environments, in which F12, Ctrl-F12, and Ctrl-Q become my best friends.

Component Organization

These are all the same thing?

Functional Organization

On the other hand, functional organization is based upon the idea of spatial locality: it is more efficient to keep items that are often used together near each other. The underlying concept is functional cohesion, which means that entities which work toward the same goal or purpose should go together. Going back to the baseball analogy, this would simply imply that players from each team should go together, regardless of their positions, because they play together and operate as a functional unit on that team.

As applied to a .NET software solution, classes and other objects are grouped together in folders or projects based upon their use case , or what purpose they serve—e.g. RegisterOrUpdateEmployee , GetPaidTimeOffPolicyList , etc. The benefit to this approach is that it's easier to navigate the solution, especially as it grows, and it helps you to maintain a high level of cohesion around different use cases of the system. Some of the downsides to this are that you might break from framework conventions, lose automatic scaffolding from certain tools, and so on. Personally, I think it's worth the cost. As an aside, it's worth noting that Angular uses functional organization by default, so this isn't a totally radical methodology.

Functional Organization

These all work well together.

In my architecture I use functional organization to the greatest extent possible, where it makes sense . Once again, the 80/20 rule (Pareto principle) applies. In situations where it doesn't make sense, I fall back to component organization. In Renze's demo solution he mixes unit test classes into the same folders as the classes under test within the application projects. DON'T EVER DO THIS. Unit tests are a different animal, and they belong in their own projects. Once again, principles and practices are guidance, general rules to follow, and as the character Morpheus states in the Matrix , "some of them can be bent, others can be broken."

When applied to the architectural layers of a Clean DDD solution, functional organization looks like this. Layer/grouping:

  • Domain - Each domain entity
  • Application - Aggregate root corresponding to each use case
  • Persistence - Each database table
  • Infrastructure - Each functional area of the operating system (file operations, etc.) and/or external resources
  • Presentation - Aggregate root corresponding to each screen or web page
  • Cross-cutting (Common) - Each cross-cutting concern (Logging, Security, etc.)

The Template

Just as a refresher, here is what the architecture looks like at a high level.

Clean Domain Driven-Design, Jacobs Interpretation

Core Layers

As stated in the previous entry, the core is comprised of the Domain layer and the Application layer. Think of this as the "zone of abstractions and logic".

Domain Layer Organization

Domain Layer Organization

Once again, the Domain Layer should have no knowledge of outside layers, even by proxy (i.e. by exposing interfaces which are implemented by outside layers). It is strictly for business entities and logic.

Key points:

  • I start with a single Domain project, in which I create root-level folders that hold base classes corresponding to different key DDD concepts—Models, Events, so on. Additional projects can be added, for instance to separate out bounded contexts, but this is the main one.
  • I also have a separate root level folder to house interfaces and other abstractions. I've named this Abstractions, and it's pretty similar to the way that the official .NET Core packages are structured. In fact, at some point in the future we could even separate this into its own project. This is a recurring pattern throughout the layers.
  • There is a Common folder at the root level as well, which holds various Domain entities and value objects that don't belong to any particular bounded context. This is essentially a "shared kernel" in DDD-speak. Note that this pattern doesn't just apply to the Domain layer. Anything which cuts across Bounded Contexts goes into a "Common" folder for each layer.
  • Additional root level folders exist for each bounded context. In the future, as the solution scales, each one can be broken off into its own project with little refactoring involved, if we continue to abide by the Fungibility principle I stated above. You can see this in the demo app, where I have created a separate Domain project for the Accounting bounded context.
  • I studied a few different ValueObject base class implementations and I settled on the one that Taylor's solution and the Microsoft e-book use. In this implementation , child classes must explicitly state which data properties are used for comparison. While this might seem like more effort, I prefer this over reflection-based approaches because the design of each value object should not be taken lightly, and furthermore you don't want to take a performance hit from using reflection in these. See below.
  • In general, the Domain layer should have zero reliance on external packages and third-party dependencies. However, if you examine the demo application, you'll see that I put in a hard dependency on MediatR as a means of dispatching domain events. Some may regard this as worthy of a slap on the wrist, but I consider it to be a situation where breaking the rules is acceptable, because trying to abstract away MediatR is simply is not worth the effort, and it wouldn't be hard to remove if the need arose to use a different in-process messaging implementation.

Finally, here are some thoughts on putting persistence abstractions (interfaces) in the domain layer. At least two of the solutions I examined do this. For example, in Khorikov's solution he puts CQRS commands into the Domain layer, and the Microsoft e-book does basically the same thing with repository interfaces. 

I don't agree with them. In my architectural template, CQRS commands and queries, and repository interfaces (if you choose to use them) NEVER go into the Domain layer, because they have nothing to do with pure business logic. Persistence logic, even through interfaces, does not belong in there. In this respect, my architecture is more conservative than other Clean DDD solutions—the Domain layer should ONLY be concerned with business logic and interaction among domain entities. The Application layer is the appropriate place to put persistence interfaces because that is the layer of orchestration and coordination.

Application Layer Organization

Application Layer Organization 1

In my opinion, this is the most important layer in the entire architecture, so I'll go into some detail on this. 

  • IOrgManagerDbContext - This is a facade which abstracts away an Entity Framework Core database context for our application data. This will be used almost exclusively on the command side of the stack.
  • IOrgManagerDbQueryFacade - This is a facade which abstracts away calls to a micro-ORM called Dapper. This will be used mostly on the query side of the stack, although there's no restriction against using this inside commands, should the need arise.
  • There is a Common folder in here as well. Think of it as a higher-level shared kernel. In here are subfolders, each of which corresponds to a separate Entity Framework Core entity, which in turn will map to a database table, since we're using EF code-first. You might be wondering why this is not broken apart by bounded context as well. The reason is simple: we are only targeting one database. As stated earlier, the approach is to build a monolithic application comprised of several projects, which can be broken apart into separate microservices at some later date. When (if) that time comes, we can worry about splitting the data model.
  • Also, at the root level there are folders corresponding to different bounded contexts. Just like with the Domain layer, these can be moved into separate projects, should the need arise. Each bounded context folder has subfolders corresponding to each aggregate root. Inside each of these, we've separated our commands from queries. See below on how this could scale, should the need arise to split the stack.
  • This layer may reference "helper" libraries such as mappers, internal messaging components (MediatR).
  • As stated in the previous blog entry, the use of the Mediator pattern along with CQRS is almost a no-brainer. Encapsulating commands/queries as MediatR requests is how we accomplish this.
  • We get additional benefits, such as being able to inject cross-cutting concerns into the request pipeline, which is exactly what I've done. The RequestCachingBehavior that I've implemented is a great example of this.

Application Model Classes

Remember from the last entry what I said about view models? To recap, they are models that map to some piece of the UI and are used to communicate back and forth between the UI and the Presentation layer (web API). In this architecture I treat both CQRS commands and the DTOs that are returned from queries as view models. This might strike you as wrong or otherwise violating the Single Responsibility principle, but in this instance it's okay. This is because the task-based orientation of CQRS functionally aligns with the UI, so there's typically a 1:1 correspondence between the models that present information to the user and those that are required/produced by CQRS commands and queries. Furthermore, if there comes a time when the two must be decoupled, there's nothing from stopping us from doing that and putting that mapping logic into the Presentation layer.

The persistence models are a different story... Several the solutions I studied were reusing the EF Core model classes as Domain entities. NO, NO, NO, NO! Even Taylor's solution does this, and his architecture is the closest to mine out of all them. I disagree with virtually all the experts on this. Here's why:

Persistence model classes never quite map perfectly to database tables and queries because of what Greg Young calls an object-relational impedance mismatch . This sounds complicated but it's not. All it means is that databases and programming languages differ in the way they represent data and relationships between entities, so of necessity there always must be some degree of translation going on. More specifically, databases are (traditionally) relational, which means that they are based upon Set Theory . Modern programming frameworks are (often) object-oriented, which means that they are based on Graph Theory . Furthermore, databases have their own data types which are almost always different from the data types used in your programming language of choice, so conversion or even data loss is involved when communicating between the two. If you are using an ORM like Entity Framework, then it will handle this for you. If you are writing straight ADO.NET code, then you have to deal with the pain of mapping between them yourself.

Taking this a step further, domain entities and persistence entities have radically different intents: one is used to model the business and the other is used to store data. The accepted answer from this stack exchange question , by Robert Bräutigam, explains it quite well:

DDD and EF have little to nothing to do with each other. DDD is a modeling concept. It means to think about the Domain, the Business Requirements, and model those. Especially in the context of object-orientation it means to create a design which mirrors business functions and capabilities. EF is a persistence technology. It is mainly concerned with data and database records. These two are sharply divorced. A DDD design may use EF in some form under the hood, but the two should not interact in any other way. Some interpretations of Domain-Driven Design do advocate data-modeling, and I think this is what your question is about. In this interpretation "Entities" and "Value Objects" are essentially function-less data holders only, and the design concerns itself with what properties these hold and what relation they have between each other. In this context DDD vs. EF may come up. This interpretation however is flawed, and I would strongly recommend ignoring it altogether. In conclusion: DDD and EF are not mutually exclusive, they are actually irrelevant to each other, as long as you are doing proper object-modeling and not data-modeling. DDD objects should not in any shape or form be EF artifacts. DDD Entities should not be EF "entities" for example. Inside some business-relevant function, a DDD design might use EF with some related data-objects, but those should be always hidden under a business-relevant behavior-oriented interface.

One solution to avoid getting tangled in this mess is to use mapping. You'll notice that the folders corresponding to different commands/queries have mapper classes which allow you to map from view models to domain models, and back again. Additionally, the folders corresponding to different database tables have mapper classes that allow you to map from persistence entities to domain models, and back again as well. This is the price that we must pay for using a Clean DDD approach because it's important to maintain the decoupling between Domain layer entities and view models/persistence entities. This is the biggest pain point in this architecture, but fortunately that pain can be minimized by using tools such as AutoMapper or Mapster. I've abstracted the mappers for each entity pair behind interfaces, because this makes our solution much more testable and flexible. Dependency injection is used to provide the actual implementations to the command/query classes that need them.

Persistence Entities and Facades

You might be questioning why view models and persistence models are declared in the Application layer instead of Presentation/Persistence. The answer, quite simply, is because the Application layer is doing all the heavy lifting in the system and depends upon them to manipulate the data model inside command handlers, and relay query results back up the stack from inside of query handlers.

Remember from the last entry, in which I talked about the asymmetry of the solution? You can clearly see this in the Application and Persistence layers, in which I'm using two different persistence technologies: Entity Framework Core and Dapper.

  • EF Core is Microsoft's ORM for .NET Core. I'm using this on the command/write side of the stack because it makes inserting and updating data to the database much easier. It can also be used for simple queries against the database inside CQRS commands. I've abstracted the EF Core DbContext behind an interface which gets injected into CQRS command handlers.
  • Dapper is a lightweight micro-ORM. I'm using this on the query/read side of the stack because it facilitates writing complex database queries without incurring the performance penalties typically associated with ORMs, including EF Core. I've abstracted a few key Dapper methods behind a query facade interface which gets injected into the CQRS query handlers.

You'll notice that the IOrgManagerDbContext and  IOrgManagerDbQueryFacade interfaces still allow CQRS command/query handlers to use LINQ and/or straight SQL queries. Aren't these leaky abstractions—i.e. allowing database details into the Application layer? In a sense, yes. Technically I've broken another rule and I'm sure Uncle Bob would yell at me for this. However, I'm of the camp that trying to create a "pure" abstraction that removes ALL knowledge of the underlying data store is not worth the effort, because the paradigms underlying various data stores can be so radically different that it's difficult to keep underlying details from leaking across the interface boundary anyway. What if the underlying data store is a NoSQL database? Or the file system? The Repository pattern attempts to do mitigate this problem, but I'm not a fan of using it in CQRS solutions. Read on.

To Repo, or Not to Repo?

I disagree with a few the experts on the use of the Repository pattern. In my opinion, repositories are an unnecessary abstraction in CQRS solutions—they are trying to solve a problem which doesn't exist, which is the encapsulation of task-based operations into a Unit of Work ; the commands themselves already do this. Furthermore, I believe that repositories can tend to sway you toward CRUD-type semantics, whereas CQRS commands (ideally) are unambiguously centered around business tasks. I'm not 100% against repositories, but I think they are more appropriate for CRUD applications.

While it's true that forgoing the use of repositories and writing LINQ/SQL queries directly in the CQRS handlers isn't truly persistence agnostic, it is still flexible enough that we can swap out one database provider for another (in theory). Regarding testability, we still maintain the ability to write unit tests against our CQRS handlers by mocking out the persistence facade interfaces.

Periphery Layers

The periphery is comprised of the Persistence, Infrastructure, and Presentation layers. Think of this as the "zone of implementations and concretes." Honestly, I'm not going to go into great detail with these because they are self-explanatory.

Persistence Layer Organization

Persistence Layer Organization

It's important to mention that another benefit to using Entity Framework Core is that it allows us to scaffold our database from the persistence model classes, which can be a huge time saver and result in a clean, robust database schema. That's exactly what I've done, so the EF configuration classes are in here, functionally organized into subfolders, along with the EF code migrations.

The Persistence layer additionally houses the implementations for the EF Core DbContext interface and the Dapper QueryFacade interface.

Infrastructure Layer Organization

Infrastructure Layer Organization

This is very similar to the Persistence layer. The Infrastructure layer contains concrete implementations for abstractions that are defined in the Application layer relating to things like Identity, accessing the file system, external messaging, and so on. Likewise, implementations for abstractions defined in the Common layer should also go in here, a good example being the IDateTime interface, discussed below.

You might be wondering why Identity is in here instead of in the Persistence layer. The reason is that Identity is an entirely separate architectural area from persistence, and there's no reason to assume that user identity will be backed by a DB, as opposed to some third-party identity store accessed through an API (there are dozens out there).

Presentation Layer Organization

Presentation Layer Organization

For all intents and purposes the Presentation layer is the top of the stack as far as back end code is concerned. The UI is treated separately. In the finished solution, this will be an ASP.NET Core web API with thin logic inside of it. The only code inside here will be:

  • ASP.NET Core boilerplate, to get the web API up and running.
  • Controllers, which act as the REST interface that the UI will communicate with.
  • High-level components, namely from the Application layer, which get injected into the controllers and called as a consequence of various controller actions. All these components are wired together using an IOC container and dependency injection.

While keeping the Presentation layer decoupled from the Application layer is a must, decoupling from the UI isn't as big of a deal. At some point in the future, should we feel the need, there is nothing to stop us from peeling off the Presentation layer and replace it with a desktop UI, implemented using WPF. In this case, the Presentation layer is the UI. Alternatively, we can unplug the stack starting from the Application layer on down and put it inside a different web API, one that is specifically targeted toward mobile clients. Anything is possible.

In some of the other demo solutions I studied, the web API project was treated as the Application layer. I don't agree with this. My stance is to treat the Web API project as belonging to the Presentation Layer (as distinct from the UI). This coincides with the Taylor solution and provides for much better decoupling at an architectural level.

Common Layer Organization

Common Layer Organization

There isn't much going on here, just your usual cross-cutting concerns like text manipulation and the like. As always, be careful what you put into this layer and make sure that it's a cross-cutting concern.

Here's a short explanation of the  IDateTime interface. This is in here because it's used by virtually every layer, including the Domain layer. The actual implementation for it is in the Infrastructure layer. This is something you might take for granted, but it is an incredibly powerful pattern. Some of the benefits are:

  • All components and logic which are dependent upon the system date/time instantly become unit testable.
  • What's more, if you have a system which is highly sensitive to the current date/time, you can put a special implementation behind this, and all subsystems will stay in sync.
  • I'd take this further and put in the provision that all date/times must be in UTC across the whole stack, except when being presented to the user. The reasons for this are numerous, but suffice it to say, I've acquired this point of view after working on dozens of legacy systems which DON'T do this.

Unit Test Projects

Unit Tests Organization

When adding unit tests to a solution, I largely follow the conventions espoused by Roy Osherove in his book The Art of Unit Testing . For instance, the folder structure of unit test projects should mirror the folder structure of the projects under test, and each test should be cohesive and test only one thing. In terms of code coverage, 100% is rarely feasible or necessary. Aim to test the most critical pieces first. Test-driven development (TDD) is easier when using CQRS, and I may touch on that in a future post. If you've designed them well and are using dependency injection properly, then command/query handlers should be easily unit testable.

Points for Style: F# Projects

F# Project

In the demo application I've added an F# project to the solution, representing specialized logic in the Domain layer for a bounded context. This is just to demonstrate how easy it is to create multi-paradigm solutions, and the way that I dovetail F# code into a .NET solution which is mainly built using C#. As stated in the blog entry on DDD, functional programming techniques are extremely powerful when used to implement domain logic. In this kind of a scenario, anemic domain models are okay, because the business rules are encapsulated inside functions. I'm not going to do a lot in the future using F# in the demo application, however a complete multi-paradigm solution would probably be comprised of 80% C# code, and 20% F# code. This gives you an idea of what's possible.

Example code for a domain class built using F#.

Layer Interaction

Simplistically, this demonstrates how the layers interact with each other.

Layer Interaction

In this entry I went into detail about how to implement Clean DDD and CQRS in a .NET Core solution. I mentioned some of the experts whose solutions I studied and spoke a little bit about some of their solutions. I presented the use case for a fictional company to create an organization management tool, and I introduced the demo application. I laid out some of the code-level conventions and project-level guidelines for organizing the solution, and I talked about functional organization vs. component organization. Finally, I went into detail about each layer of the architecture, building off the concepts presented in the previous blog entry. Finally, I introduced unit tests at a surface level, and I wrapped up by pointing the way toward building multi-paradigm solutions, which combine both functional F# code with OOP C# code.

Experts / Authorities / Resources

Robert c. martin (uncle bob).

  • Clean Coder
  • Screaming Architecture

Roy Osherove

  • Roy Osherove - Home
  • The Art of Unit Testing (Book)

Jason Taylor

  • Clean Architecture with ASP.NET Core 2.1
  • Northwind Traders Demo App (GitHub)

Julie Lerman/Steve Smith

  • Domain-Driven Design Fundamentals
  • Domain-Driven Design Fundamentals (GitHub)

Steve Smith

  • Architect Modern Web Applications with ASP.NET Core and Azure
  • Clean Architecture (GitHub)

Jimmy Bogard

  • Jimmy Bogard - Home
  • LosTechies.com
  • MediatR (GitHub)

Matthew Renze

  • Clean Architecture: Patterns, Practices, and Principles
  • Clean Architecture Demo (GitHub)

Vladimir Khorikov

  • Domain-Driven Design in Practice
  • CQRS In Practice (GitHub)
  • CQRS Documents

Dino Esposito

  • Modern Software Architecture: Domain Models, CQRS, and Event Sourcing

Microsoft - Microservice/DDD Guide

  • .NET Microservices: Architecture for Containerized .NET Applications
  • E-Shop On Containers (GitHub)
  • CodeMaid - Home
  • Using CodeMaid (YouTube)
  • Dapper (GitHub)

This is entry #8 in the Foundational Concepts Series

If you want to view or submit comments you must accept the cookie consent.

  • Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers
  • Advertising & Talent Reach devs & technologists worldwide about your product, service or employer brand
  • OverflowAI GenAI features for Teams
  • OverflowAPI Train & fine-tune LLMs
  • Labs The future of collective knowledge sharing
  • About the company Visit the blog

Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Get early access and see previews of new features.

Why should I isolate my domain entities from my presentation layer?

One part of domain-driven design that there doesn't seem to be a lot of detail on, is how and why you should isolate your domain model from your interface. I'm trying to convince my colleagues that this is a good practice, but I don't seem to be making much headway...

They use domain entities where ever they please in the presentation and interface layers. When I argue to them that they should be using display models or DTOs to insulate the Domain layer from the interface layer, they counter that they don't see the business value in doing something like that, because now you have a UI object to maintain as well as the original domain object.

So I'm looking for some concrete reasons I can use to back this up. Specifically:

  • Why should we not use domain objects in our presentation layer? (if the answer is the obvious one, 'decoupling', then please explain why this is important in this context)
  • Should we use additional objects or constructs to isolate our domain objects from the interface?
  • design-patterns
  • architecture
  • domain-driven-design
  • presentation-layer
  • data-transfer-objects

Mark Rogers's user avatar

  • this question should be in wiki. –  Syed Tayyab Ali Commented May 4, 2009 at 18:24
  • @m4bwav - It should be a wiki because it is phrased in such a way as to invite discussion rather than a single correct answer. –  Rob Allen Commented May 4, 2009 at 18:28
  • 1 @m4bwav: I think your question came off as more of an opinion piece than a real question... I've tried to correct that (you may want to edit it further), but be aware that without proper care this might appear to be trolling. –  Shog9 Commented May 4, 2009 at 18:28
  • 5 Ok, backup, I'm asking a legitimate question, how would this offend anyone? Who am I targeting? –  Mark Rogers Commented May 4, 2009 at 18:29
  • @m4bwav: you're targeting your straw-man. The "large number of people" you discuss this with in your question. –  Shog9 Commented May 4, 2009 at 18:33

15 Answers 15

Quite simply, the reason is one of implementation and drift. Yes, your presentation layer needs to know about your business objects to be able to represent them properly. Yes, initially it looks like there is a lot of overlap between the implementation of the two types of objects. The problem is, as time goes on, things get added on both sides. Presentation changes, and the needs of the presentation layer evolve to include things that are completely independent of your business layer (color, for example). Meanwhile, your domain objects change over time, and if you don't have appropriate decoupling from your interface, you run the risk of screwing up your interface layer by making seemingly benign changes to your business objects.

Personally, I believe the best way to approach things is through the strictly enforced interface paradigm; that is, your business object layer exposes an interface that is the only way that it can be communicated with; no implementation details (i.e. domain objects) about the interface are exposed. Yes, this means that you have to implement your domain objects in two locations; your interface layer and in your BO layer. But that reimplementation, while it may initially seem like extra work, helps enforce the decoupling that will save TONS of work at some point in the future.

Paul Sonier's user avatar

  • 3 What do you mean by "implement your domain objects in two locations?" –  jlembke Commented Jun 2, 2009 at 15:50
  • 14 This just seems silly to me. Why do the extra work now that MAY save work in the future? 9 times out of 10 you'll never need to need to make the change that would save "TONS" of work. –  Beep beep Commented Nov 16, 2009 at 17:56
  • 25 @LuckyLindy: 99 times out of 100 (actually more), wearing my seat belt isn't necessary to keep me from getting injured. However, in the one instance when I really need it, it will (likely) keep me from getting killed or badly injured. An ounce of prevention is worth a pound of cure. I suspect your opinion about this will change after you have more experience. –  Paul Sonier Commented Nov 16, 2009 at 18:24

I have struggled with this myself. There are cases where a DTO makes sense to use in presentaton. Let's say I want to show a drop down of Companies in my system and I need their id to bind the value to.

Well instead of loading a CompanyObject which might have references to subscriptions or who knows what else, I could send back a DTO with the name and id. This is a good use IMHO.

Now take another example. I have an object which represents an Estimate, this estimate might be made up labor, equipment etc, it might have lots of calculations that are defined by the user which take all these items and sum them up (Each estimate could be different with different types of calculations). Why should I have to model this object twice? Why can't I simply have my UI enumerate over the calculations and display them?

I generally do not use DTO's to isolate my domain layer from my UI. I do use them to isolate my domain layer from a boundary that is outside of my control. The idea that someone would put navigation information in their business object is ridiculous, don't contaminate your business object.

The idea that someone would put validation in their business object? Well I say that this is a good thing. Your UI should not have sole responsability to validate your business objects. Your business layer MUST do its own validation.

Why would you put UI generation code in a busienss object? In my case I have seperate objects which generates the UI code seperatley from the UI. I have sperate objects which render my business objects into Xml, the idea that you have to seperate your layers to prevent this type of contamination is so alien to me because why would you even put HTML generation code in a business object...

Edit As I think a little bit more, there are cases where UI information might belong in the domain layer. And this might cloud what you call a domain layer but I worked on a multi-tenant application, which had very different behavior both UI look and feel and functional workflow. Depending on various factors. In this case we had a domain model that represented the tenants and their configuration. Their configuration happened to include UI information (Label's for generic fields for example).

If I had to design my objects to make them persistable, should I also have to duplicate the objects? Keep in mind if you want to add a new field now you have two places to add it. Perhaps this raises another question if your using DDD, are all persisted entities domain objects? I know in my example they were.

JoshBerke's user avatar

  • 1 Wouldn't the labels being different for different tenants indicate a different ubiquitous language for each tenant? I think there needs to be the concept of a meta-model where a domain is shared among tenants with a translation layer to their interpretation of the meta-model. –  Kell Commented Jun 6, 2016 at 10:46

I disagree.

I think the best way to go is to start with domain objects in your presentation layer UNTIL IT MAKES SENSE TO DO OTHERWISE.

Contrary to popular belief, "Domain Objects" and "Value Objects" can happily co-exist in the presentation layer. And this is the best way to do it - you get the benefit of both worlds, reduced duplication (and boilerplate code) with the domain objects; and the tailoring and conceptual simplification of using value objects across requests.

Daniel Alexiuc's user avatar

  • Thanks for your input, I see where your coming from. While I'm not saying that this isn't another of the infinite ways to create a successful project, it seems to run counter to the "Domain-Driven Design" style, which is for larger and more complex projects that are harder to maintain in the long run. –  Mark Rogers Commented May 14, 2009 at 14:08
  • No, this is wrong, and exactly why so many sites end up vulnerable to sql injection. –  Cookie Commented Nov 8, 2017 at 15:18

You do it for the same reason you keep SQL out of your ASP/JSP pages.

If you keep only one domain object, for use in the presentation AND domain layer, then that one object soon gets monolithic. It starts to include UI validation code, UI navigation code, and UI generation code. Then, you soon add all of the business layer methods on top of that. Now your business layer and UI are all mixed up, and all of them are messing around at the domain entity layer.

You want to reuse that nifty UI widget in another app? Well, You have to create a database with this name, these two schemas, and these 18 tables. You must also configure Hibernate and Spring ( or your frameworks of choice ) to do the business validation. Oh, you must also include these 85 other non-related classes because they are referenced in the business layer, which just happens to be in the same file.

digitaljoel's user avatar

Answer depends on scale of your application.

Simple CRUD (Create, Read, Update, Delete) application

For basic crud applications you do not have any functionality. Adding DTO on top of entities woudl be a waste of time. It would increase complexity without increasing scalability.

enter image description here

Moderately complicated Non-CRUD application

In this size of application you will have few entities which have true lifeclycle and some business logic associated with them.

Adding DTOs on this case is a good idea for few reasons:

  • Presentation layer can see only subset of fields which entity has. You encapsulate Entities
  • No coupling between backend and frontent
  • If you have business methods inside entities, but not in DTO then adding DTOs means that outside code can't ruin state of your entity.

enter image description here

Complicated Enterprise Application

Single entity might need multiple ways of presentation. Each of them will need different set of fields. In this case you encounter the same issues as in previous example plus need to control amount of fields visible for each client. Having separate DTO for each client will help you to chose what should be visible.

enter image description here

We are using the same model in the server and on the ui. And it's a pain. We have to refactor it some day.

The problems are mainly because the domain model needs to be cut into smaller pieces to be able to serialize it without having the whole database referenced. This makes it harder to use on the server. Important links are missing. Some types are also not serializable and can't be sent to the client. For instance 'Type' or any generic class. They need to be non-generic and Type needs to be transferred as string. This generates extra properties for serialization, they are redundant and confusing.

Another problem is that the entities on the UI don't really fit. We are using databinding and many entities have lots of redundant properties only for ui purposes. Additionally there are many 'BrowsableAttribute' and others in the entity model. This is really bad.

At the end, I think it is just a matter of which way is easier. There might by projects where it just works fine and where is no need to write another DTO model.

Stefan Steinegger's user avatar

  • 2 If your going to use databinding run a linq query and bind to an anonymous type. This lets you flatten and change the heirarchy. You can also implement filtering and sorting very nicely with this. –  JoshBerke Commented May 4, 2009 at 18:55
  • @Josh: Thanks for the advise. This might partially work. I'm not a GUI programmer myself and am not involved in GUI concepts much. The problem will be in cases where the data is manipulated and sent back to the server. –  Stefan Steinegger Commented May 4, 2009 at 19:38

Dammit, I swear this said persistence.

Anyway, it's one more instance of the same thing: Parnas's law says a module should keep a secret, and the secret is a requirement that can change. (Bob Martin has a rule that's another version of this.) In a system like this, the presentation can change independently of the domain . Such as, for example, a company that maintains prices in Euros and uses French in the company offices, but wants to present prices in dollars with text in Mandarin. The domain is the same; the presentation can change. So, to minimize the brittleness of the system — that is, the number of things that must be changed to implement a change in requirements — you separate the concerns.

Charlie Martin's user avatar

It's about dependencies for the most part. The core functional structure of the organization has its own functional requirements, and the UI should enable people to modify and view the core; but the core itself should not be required to accommodate the UI. (If it needs to happen, it's usually an indication the core is not property designed.)

My accounting system has a structure and content (and data) that are supposed to model the operation of my company. That structure is real and exists regardless of what accounting software I use. (Inevitably a given software package contains structure and content for its own sake, but part of the challenge is minimizing this overhead.)

Basically a person has a job to do. The DDD should match the flow and content of the job. DDD is about making explicit all the jobs that need being done ad completely and independently as possible. Then the UI hopefully facilitates getting the job done as transparently as possible, as productively as possible.

Interfaces are about the inputs and views provided for the properly modeled and invariant functional core.

dkretz's user avatar

Your presentation may reference your domain layer, but there should be no binding directly from your ui to your domain objects. Domain objects are not intended for UI usage since they are often, if properly designed, based around behaviors and not data representations. There should be a mapping layer between the UI and the Domain. MVVM, or MVP, is a good pattern for this. If you try to directly bind your UI to the Domain, you will probalby create a lot of headache for yourself. They have two different purposes.

jlembke's user avatar

Here's a real example as to why I find it good practice to separate domain entities from the view.

A few months ago I created a simple UI to show the values of Nitrogen, Phosphorus and Potassium in a soil sample through a series of 3 gauges. Each gauge had a red, green and red section, i.e. you could either have too little or too much of each component, but there was a safe green level in the middle.

Without much thought, I modelled my business logic to supply data for these 3 chemical components and a separate data sheet, containing data about the accepted levels in each of the 3 cases (including which measurement unit was being used, i.e. moles or percentage). I then modelled my UI to use a very different model, this model was concerned about gauge labels, values, boundary values and colours.

This meant when I later had to show 12 components, I just mapped the extra data into 12 new gauge view models and they appeared on the screen. It also meant I could reuse the gauge control easily and have them display other data sets.

If I'd had coupled these gauges directly into my domain entities, I would not have any of the above flexibility and any future modifications would be a headache. I've come across very similar issues when modelling calendars in the UI. If there is a requirement for a calendar appointment to turn red when there are 10+ attendees, then the business logic to handle this should remain in the business layer and all the calendar in the UI needs to know, is that it has been instructed to turn red, it should not need to know why.

Adrian Thompson Phillips's user avatar

Perhaps you are not conceptualizing the UI layer in broad enough terms. Think in terms of multiple forms of response (web pages, voice response, printed letters etc) and in terms of multiple languages (English, French etc.).

Now suppose that the speech engine for the telephone call-in system runs on a completely different type of computer (Mac for example) from the computer that runs the website (Windows perhaps).

Of course it is easy to fall into the trap "Well in my company we only care about English, run our website on LAMP (Linux, Apache, MySQL and PHP) and everyone uses the same version of Firefox". But what about in 5 or 10 years?

JonnyBoats's user avatar

See also the section "Data propagation between layers" in the following, which I think presents compelling arguments:

http://galaxy.andromda.org/docs/andromda-documentation/andromda-getting-started-java/java/index.html

With the help of tool like ' Value Injecter ' and the concept of 'Mappers' in the presentation layer while working with views, it's much more easy to understand each piece of code. If you have a little bit of code, you will not see the advantages immediately but when your project will growing more and more, you will be very happy while working with the views to don't have to enter into the logic of the services, repositories to understand the view model. View Model is another guard in the vast world of anti-corruption layer and worth its weight in gold in a long term project.

The only reason why I see no advantage of using view model is if your project is small and simple enough to have views binded directly to each property of your model. But if in the futur, the requirement change and some controls in the views will not be binded to the model and you don't have a view model concept, you will start adding patches in many places and you will begin having a legacy code that you will not appreciate. Sure, you can do some refactoring to transform your view-model in view-viewmodel and follow the YAGNI principle while not adding code if you don't need it but for myself, it's much more a best practice that I must follow to add a presentation layer exposing only view-model objects.

Samuel's user avatar

A good practice for good practices sake is not always business efficient. If justified, I'm more than happy to argue against using CQRS, Event Sourcing, DDD, etc. For example, on smaller projects that have one or two use-cases.

While the other answers are excellent, the concerns that convinced me that decoupling is important hasn't been mentioned: Your repository (ORM) may populate data unexpectedly.

For example, consider these two actions accessing an Entity Framework DbContext : (I've not tested this code, but it should get the point across)

While both actions return a JSON object of a User, due to Entity Framework's Object Caching, the second action will include the Roles property—without explicitly asking for it on the final line.

If your application or persistence/infrastructure layer conditionally Includes properties, then your Domain object properties will be conditionally instantiated and you may get unexpected results.

Due to this, and the great reasons provided by other answers, I'm convinced to no longer expose my domain objects to my presentation layer.

Finally, I'm not against using Anonymous objects in place of Dto's—especially when type safety is lost with JsonResult .

For example:

Nathan Goings's user avatar

The only sensible reason for adding additional mapping between generalized and domain specific semantics is that you have (access to) an existing body of code (and tools) that are based on a generalized (but mappable) semantics distinct from your domain semantics.

Domain driven designs work best when used in conjunction with an orthogonal set of functional domain frameworks (such as ORM, GUI, Workflow, etc.). Always remember that it is only in the outer layer adjacencies that domain semantics need to be exposed. Typically this is the front end (GUI) and persistent back-end (RDBM,ORM). Any effectively designed intervening layers can and should be domain invariant.

alphazero's user avatar

  • para 1: don't create unnecessary abstraction (e.g. reusable components) unless you will actually share them across distinct apps. para 2:I wonder how generic GUIs work across so many different domains. Remark: This industry is so broken, it is not even funny anymore ... –  alphazero Commented Mar 14, 2016 at 14:36

Your Answer

Reminder: Answers generated by artificial intelligence tools are not allowed on Stack Overflow. Learn more

Sign up or log in

Post as a guest.

Required, but never shown

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy .

Not the answer you're looking for? Browse other questions tagged design-patterns architecture domain-driven-design presentation-layer data-transfer-objects or ask your own question .

  • The Overflow Blog
  • Ryan Dahl explains why Deno had to evolve with version 2.0
  • Featured on Meta
  • We've made changes to our Terms of Service & Privacy Policy - July 2024
  • Bringing clarity to status tag usage on meta sites
  • Feedback requested: How do you use tag hover descriptions for curating and do...
  • What does a new user need in a homepage experience on Stack Overflow?

Hot Network Questions

  • Find all pairs of positive compatible numbers less than 100 by proof
  • Why is global state harder to test? Doesn't reset the global state at the beginning of each test solves the problem?
  • Seven different digits are placed in a row. The products of the first 3, middle 3 and last 3 are all equal. What is the middle digit?
  • My first actual cryptic
  • Reference of "she"
  • Is sudoku only one puzzle?
  • Momentary solo circuit
  • Cannot compile code against latest stable GeoTools/GeoServer version
  • Retroactively specifying `-only` or `-or-later` for GPLv2 in an adopted project
  • Do linguists have a noun for referring to pieces of commendatory language, as a sort of antonym of 'pejoratives'?
  • How did this zucchini plant cling to the zip tie?
  • For applying to a STEM research position at a U.S. research university, should a resume include a photo?
  • Is it possible for a company to dilute my shares to the point they are insignificant
  • Is the Garmin Edge 530 still a good choice for a beginner in 2024?
  • The Master Tetrist
  • How soon to fire rude and chaotic PhD student?
  • result of a union between a decidable language and not recognizable one - disjoint
  • Stacked block problem & static friction
  • Can science inform philosophy?
  • What might cause these striations in this solder joint?
  • Euler E152: "Analysin enim ineptam existimat"
  • Series of discrete groups with a Lie group limit
  • Is math a bad discipline for teaching jobs or is it just me?
  • Should I be able to see light from a IR Led with my own eyes?

presentation domain data

  • Español – América Latina
  • Português – Brasil
  • Tiếng Việt
  • Android Developers

Domain layer

The domain layer is an optional layer that sits between the UI layer and the data layer.

presentation domain data

The domain layer is responsible for encapsulating complex business logic, or simple business logic that is reused by multiple ViewModels. This layer is optional because not all apps will have these requirements. You should only use it when needed-for example, to handle complexity or favor reusability.

A domain layer provides the following benefits:

  • It avoids code duplication.
  • It improves readability in classes that use domain layer classes.
  • It improves the testability of the app.
  • It avoids large classes by allowing you to split responsibilities.

To keep these classes simple and lightweight, each use case should only have responsibility over a single functionality, and they should not contain mutable data. You should instead handle mutable data in your UI or data layers.

Naming conventions in this guide

In this guide, use cases are named after the single action they're responsible for. The convention is as follows:

verb in present tense + noun/what (optional) + UseCase .

For example: FormatDateUseCase , LogOutUserUseCase , GetLatestNewsWithAuthorsUseCase , or MakeLoginRequestUseCase .

Dependencies

In a typical app architecture, use case classes fit between ViewModels from the UI layer and repositories from the data layer. This means that use case classes usually depend on repository classes, and they communicate with the UI layer the same way repositories do—using either callbacks (for Java) or coroutines (for Kotlin). To learn more about this, see the data layer page .

For example, in your app, you might have a use case class that fetches data from a news repository and an author repository, and combines them:

Because use cases contain reusable logic, they can also be used by other use cases. It's normal to have multiple levels of use cases in the domain layer. For example, the use case defined in the example below can make use of the FormatDateUseCase use case if multiple classes from the UI layer rely on time zones to display the proper message on the screen:

presentation domain data

Call use cases in Kotlin

In Kotlin, you can make use case class instances callable as functions by defining the invoke() function with the operator modifier. See the following example:

In this example, the invoke() method in FormatDateUseCase allows you to call instances of the class as if they were functions. The invoke() method is not restricted to any specific signature—it can take any number of parameters and return any type. You can also overload invoke() with different signatures in your class. You'd call the use case from the example above as follows:

To learn more about the invoke() operator, see the Kotlin docs .

Use cases don't have their own lifecycle. Instead, they're scoped to the class that uses them. This means that you can call use cases from classes in the UI layer, from services, or from the Application class itself. Because use cases shouldn't contain mutable data, you should create a new instance of a use case class every time you pass it as a dependency.

Use cases from the domain layer must be main-safe ; in other words, they must be safe to call from the main thread. If use case classes perform long-running blocking operations, they are responsible for moving that logic to the appropriate thread. However, before doing that, check if those blocking operations would be better placed in other layers of the hierarchy. Typically, complex computations happen in the data layer to encourage reusability or caching. For example, a resource-intensive operation on a big list is better placed in the data layer than in the domain layer if the result needs to be cached to reuse it on multiple screens of the app.

The following example shows a use case that performs its work on a background thread:

Common tasks

This section describes how to perform common domain layer tasks.

Reusable simple business logic

You should encapsulate repeatable business logic present in the UI layer in a use case class. This makes it easier to apply any changes everywhere the logic is used. It also allows you to test the logic in isolation.

Consider the FormatDateUseCase example described earlier. If your business requirements regarding date formatting change in the future, you only need to change code in one centralized place.

Combine repositories

In a news app, you might have NewsRepository and AuthorsRepository classes that handle news and author data operations respectively. The Article class that NewsRepository exposes only contains the name of the author, but you want to display more information about the author on the screen. Author information can be obtained from the AuthorsRepository .

presentation domain data

Because the logic involves multiple repositories and can become complex, you create a GetLatestNewsWithAuthorsUseCase class to abstract the logic out of the ViewModel and make it more readable. This also makes the logic easier to test in isolation, and reusable in different parts of the app.

The logic maps all items in the news list; so even though the data layer is main-safe, this work shouldn't block the main thread because you don't know how many items it'll process. That's why the use case moves the work to a background thread using the default dispatcher.

Other consumers

Apart from the UI layer, the domain layer can be reused by other classes such as services and the Application class. Furthermore, if other platforms such as TV or Wear share codebase with the mobile app, their UI layer can also reuse use cases to get all the aforementioned benefits of the domain layer.

Data layer access restriction

One other consideration when implementing the domain layer is whether you should still allow direct access to the data layer from the UI layer, or force everything through the domain layer.

UI layer cannot access data layer directly, it must go through the Domain layer

An advantage of making this restriction is that it stops your UI from bypassing domain layer logic, for example, if you are performing analytics logging on each access request to the data layer.

However, the potentially significant disadvantage is that it forces you to add use cases even when they are just simple function calls to the data layer, which can add complexity for little benefit.

A good approach is to add use cases only when required. If you find that your UI layer is accessing data through use cases almost exclusively, it may make sense to only access data this way.

Ultimately, the decision to restrict access to the data layer comes down to your individual codebase, and whether you prefer strict rules or a more flexible approach.

General testing guidance applies when testing the domain layer. For other UI tests, developers typically use fake repositories, and it's good practice to use fake repositories when testing the domain layer as well.

The following Google samples demonstrate the use of the domain layer. Go explore them to see this guidance in practice:

Recommended for you

  • Note: link text is displayed when JavaScript is off
  • UI State production

Content and code samples on this page are subject to the licenses described in the Content License . Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.

Last updated 2024-07-02 UTC.

Stack Exchange Network

Stack Exchange network consists of 183 Q&A communities including Stack Overflow , the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Making a Data Layer that is tightly coupled to the Presentation Layer in Clean Architecture

So I've got a simple object recognition app in iOS. I am trying to create an Interface-Adapter for the machine learning / computer vision like this:

In the ViewController the input is from this delegate function:

Now, I am confused about how to make the UseCase here because obviously the Presentation Layer and the Data Layer is coupled because they need the CMSampleBuffer to function. Is it okay to do this? Because in that case, I also need to use CMSampleBuffer in the UseCase and Entity. But UseCases and Entities shouldn't know about the layers above them, right?

PS: Maybe I'll rephrase the question: What if my View/ViewModel use the same object as the Interface-Adapter/Controller (ie.the CMSampleBuffer )? Do I have to map CMSampleBuffer to DTO (say, SampleBufferDTO ), then send it to the UseCase (eg. CheckForObjectDetectionUseCase.check(with dto: SampleBufferDTO) -> Observable<DetectedObjectEntity> ), then use the Interface-Adapter with the DTO ( AppleMachineLearningAdapter.detectObject(_ dto: SampleBufferDTO) -> Observable<DetectedObjectEntity> ) in which it will map the DTO back to CMSampleBuffer .

Or just do the whole logic for object detection in the View/ViewModel without having a UseCase in-between?

BTW, I also got the same problem when trying to bind the View/ViewModel to the other layers for a video call feature where the video call services such as Twilio, Agora, etc should've been accessed behind a Controller but they are pretty much coupled with the AVFoundation and CallKit from the View.

  • clean-architecture

Bawenang Rukmoko Pardian Putra's user avatar

2 Answers 2

Most architecture styles try to achieve one "simple" thing: "The things that are volatile should depend on the stable stuff, not the other way around".

The CMSampleBuffer object is data + logic. Using a DTO for talking between layers, means that the data is kind of stable and will not change in the different usages (presentation or controller), while the logic may be different and/or will likely change differently in the different layers.

If that is the case, then it makes sense to use a DTO between layers. But, if the logic is also kind of stable, or will always change in both layers identicaly, then there is no advantage using a DTO.

Architecture is always about understanding the business and looking into the crystal ball how the business may change. We CAN try to support all possible changes (like having own entities per layer, and use mapping logic between layers), but that comes with a cost. For example flexibility is normaly bad for performance.

It is not possible to get everything. Therefore we have to get a feeling about the stable stuff and the changing stuff and then design our architecture accordingly.

So about your case: Working with DTOs and having your own entity per layer is more effort, the code is less understandable, harder to debug and less performant. At the same time CMSampleBuffer seems to be quite stable. => I would use the the entity through all layers.

JanRecker's user avatar

  • I see. I was thinking like that too. But CMSampleBuffer is not an entity since it came from the View. So the Use Case shouldn't know about its existence, right? –  Bawenang Rukmoko Pardian Putra Commented Oct 4, 2022 at 12:39
  • 1 Yes, if we completly embrace the Clean Architecture style, then we would use our own data model in the business logic and map to a different model in the outer regions (the controllers). Or reuse the model of the logic in the outer regions. As always it depends on the context which approach to use. If we use own models in each region, have a lot of mapping and then nothing changes for the rest of the application life, then it was the wrong decision. If there are some changes, then this mapping decision may save our app :-) –  JanRecker Commented Oct 5, 2022 at 7:09
  • I see. That's a good point. Thanks for the answer. –  Bawenang Rukmoko Pardian Putra Commented Oct 8, 2022 at 3:45
Now, I am confused about how to make the UseCase here because obviously the Presentation Layer and the Data Layer is coupled because they need the CMSampleBuffer to function.

Well sure they both need data but who said it has to be the same data?

enter image description here

Here you see the use case interactor transforming input data into output data. The arrows show what knows about what. The presenter doesn't know the input data exists. The controller doesn't know the output data exists. And naturally the data doesn't know anything exists.

If you're thinking that doesn't sound right. This whole clean architecture thing was supposed to be a set of rules about what layers could know about what layers. Well sure, but let me point out a little flaw:

enter image description here

This thing doesn't have a "Data Layer". If you want rules for a "Data Layer" look at some other architecture.

candied_orange's user avatar

  • This thing doesn't have a "Data Layer". If you want rules for a "Data Layer" look at some other architecture. I know that Clean Architecture doesn't have Presentation-Domain-Data layering per-se but some people (whose ideas I happen to follow) usually described this: MVx = Presentation layer; UseCases/Entities = Domain layer; Repositories/Gateways/Interface-Adapters/Controllers/etc = Data layer. Like in these articles: fernandocejas.com/blog/engineering/… , proandroiddev.com/… –  Bawenang Rukmoko Pardian Putra Commented Sep 27, 2022 at 5:37
  • BTW, the question still stands. Let me rephrase: what if my View/ViewModel use the same object as the Interface-Adapter/Controller (ie.the CMSampleBuffer )? Do I have to map CMSampleBuffer to DTO (say, SampleBufferDTO )-> send it to the UseCase (eg. CheckForObjectDetectionUseCase.check(with dto: SampleBufferDTO) -> Observable<DetectedObjectEntity> ) -> the UseCase then use the Interface-Adapter with the DTO ( AppleMachineLearningAdapter.detectObject(_ dto: SampleBufferDTO) -> Observable<DetectedObjectEntity> ) in which it will map the DTO back to CMSampleBuffer first before being used? –  Bawenang Rukmoko Pardian Putra Commented Sep 27, 2022 at 5:46

Your Answer

Reminder: Answers generated by artificial intelligence tools are not allowed on Software Engineering Stack Exchange. Learn more

Sign up or log in

Post as a guest.

Required, but never shown

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy .

Not the answer you're looking for? Browse other questions tagged clean-architecture coupling or ask your own question .

  • The Overflow Blog
  • Ryan Dahl explains why Deno had to evolve with version 2.0
  • Featured on Meta
  • We've made changes to our Terms of Service & Privacy Policy - July 2024
  • Bringing clarity to status tag usage on meta sites

Hot Network Questions

  • How did this zucchini plant cling to the zip tie?
  • Is sudoku only one puzzle?
  • Did polls adjust their methodology after overestimating Democrat's shares in the 2016 and 2020 presidential elections in the Rust Belt?
  • Passport - small damage on passport
  • Why is global state harder to test? Doesn't reset the global state at the beginning of each test solves the problem?
  • Is "UN law" a thing?
  • Meaning of 勸諭, especially 諭
  • Are there any well-known political considerations for having a friend on the job market come for a visit and talk?
  • The beloved shepherd isn't Solomon?
  • Strange bearings of Shimano FH-MT410-B
  • What is this surface feature near Shackleton crater classified as?
  • What other goals could a space project with the primary goal of experience building with heavy lift rockets preform?
  • Would it take less thrust overall to put an object into higher orbit?
  • Solving a systeam of two equations for only real solutions
  • Do linguists have a noun for referring to pieces of commendatory language, as a sort of antonym of 'pejoratives'?
  • Why would an incumbent politician or party need to be re-elected to fulfill a campaign promise?
  • How to remove a file named "."?
  • Who said "If you don't do politics, politics will do you"?
  • Why name the staves in LilyPond's "published" "Solo piano" template?
  • result of a union between a decidable language and not recognizable one - disjoint
  • How many people could we get off of the planet in a month?
  • Is there a word/phrase that describes things people say to be "the smartest person in the room"?
  • How to make outhouses less icky?
  • Does a cube under high pressure transform into a ball?

presentation domain data

  • Engineering Mathematics
  • Discrete Mathematics
  • Operating System
  • Computer Networks
  • Digital Logic and Design
  • C Programming
  • Data Structures
  • Theory of Computation
  • Compiler Design
  • Computer Org and Architecture

Presentation Layer in OSI model

Prerequisite : OSI Model

Introduction : Presentation Layer is the 6th layer in the Open System Interconnection (OSI) model. This layer is also known as Translation layer, as this layer serves as a data translator for the network. The data which this layer receives from the Application Layer is extracted and manipulated here as per the required format to transmit over the network. The main responsibility of this layer is to provide or define the data format and encryption. The presentation layer is also called as Syntax layer since it is responsible for maintaining the proper syntax of the data which it either receives or transmits to other layer(s).

Functions of Presentation Layer :

The presentation layer, being the 6th layer in the OSI model, performs several types of functions, which are described below-

  • Presentation layer format and encrypts data to be sent across the network.
  • This layer takes care that the data is sent in such a way that the receiver will understand the information (data) and will be able to use the data efficiently and effectively.
  • This layer manages the abstract data structures and allows high-level data structures (example- banking records), which are to be defined or exchanged.
  • This layer carries out the encryption at the transmitter and decryption at the receiver.
  • This layer carries out data compression to reduce the bandwidth of the data to be transmitted (the primary goal of data compression is to reduce the number of bits which is to be transmitted).
  • This layer is responsible for interoperability (ability of computers to exchange and make use of information) between encoding methods as different computers use different encoding methods.
  • This layer basically deals with the presentation part of the data.
  • Presentation layer, carries out the data compression (number of bits reduction while transmission), which in return improves the data throughput.
  • This layer also deals with the issues of string representation.
  • The presentation layer is also responsible for integrating all the formats into a standardized format for efficient and effective communication.
  • This layer encodes the message from the user-dependent format to the common format and vice-versa for communication between dissimilar systems.
  • This layer deals with the syntax and semantics of the messages.
  • This layer also ensures that the messages which are to be presented to the upper as well as the lower layer should be standardized as well as in an accurate format too.
  • Presentation layer is also responsible for translation, formatting, and delivery of information for processing or display.
  • This layer also performs serialization (process of translating a data structure or an object into a format that can be stored or transmitted easily).

Features of Presentation Layer in the OSI model: Presentation layer, being the 6th layer in the OSI model, plays a vital role while communication is taking place between two devices in a network.

List of features which are provided by the presentation layer are:

  • Presentation layer could apply certain sophisticated compression techniques, so fewer bytes of data are required to represent the information when it is sent over the network.
  • If two or more devices are communicating over an encrypted connection, then this presentation layer is responsible for adding encryption on the sender’s end as well as the decoding the encryption on the receiver’s end so that it can represent the application layer with unencrypted, readable data.
  • This layer formats and encrypts data to be sent over a network, providing freedom from compatibility problems.
  • This presentation layer also negotiates the Transfer Syntax.
  • This presentation layer is also responsible for compressing data it receives from the application layer before delivering it to the session layer (which is the 5th layer in the OSI model) and thus improves the speed as well as the efficiency of communication by minimizing the amount of the data to be transferred.

Working of Presentation Layer in the OSI model : Presentation layer in the OSI model, as a translator, converts the data sent by the application layer of the transmitting node into an acceptable and compatible data format based on the applicable network protocol and architecture.  Upon arrival at the receiving computer, the presentation layer translates data into an acceptable format usable by the application layer. Basically, in other words, this layer takes care of any issues occurring when transmitted data must be viewed in a format different from the original format. Being the functional part of the OSI mode, the presentation layer performs a multitude (large number of) data conversion algorithms and character translation functions. Mainly, this layer is responsible for managing two network characteristics: protocol (set of rules) and architecture.

Presentation Layer Protocols : Presentation layer being the 6th layer, but the most important layer in the OSI model performs several types of functionalities, which makes sure that data which is being transferred or received should be accurate or clear to all the devices which are there in a closed network. Presentation Layer, for performing translations or other specified functions, needs to use certain protocols which are defined below –

  • Apple Filing Protocol (AFP): Apple Filing Protocol is the proprietary network protocol (communications protocol) that offers services to macOS or the classic macOS. This is basically the network file control protocol specifically designed for Mac-based platforms.
  • Lightweight Presentation Protocol (LPP): Lightweight Presentation Protocol is that protocol which is used to provide ISO presentation services on the top of TCP/IP based protocol stacks.
  • NetWare Core Protocol (NCP): NetWare Core Protocol is the network protocol which is used to access file, print, directory, clock synchronization, messaging, remote command execution and other network service functions.
  • Network Data Representation (NDR): Network Data Representation is basically the implementation of the presentation layer in the OSI model, which provides or defines various primitive data types, constructed data types and also several types of data representations.
  • External Data Representation (XDR): External Data Representation (XDR) is the standard for the description and encoding of data. It is useful for transferring data between computer architectures and has been used to communicate data between very diverse machines. Converting from local representation to XDR is called encoding, whereas converting XDR into local representation is called decoding.
  • Secure Socket Layer (SSL): The Secure Socket Layer protocol provides security to the data that is being transferred between the web browser and the server. SSL encrypts the link between a web server and a browser, which ensures that all data passed between them remains private and free from attacks.

author

Please Login to comment...

Similar reads, improve your coding skills with practice.

 alt=

What kind of Experience do you want to share?

Presentation Domain Separation

9 October 2003

Martin Fowler

application architecture

One of the most useful design principles that I've found and followed is that of keeping a good separation between the presentation aspects of a program (the user interface) and the rest of the functionality. Over the years where I've seen this done, I've seen plenty of benefits:

  • Presentation logic and domain logic are easier to understand when separate.
  • You can support multiple presentations on the same base program without duplicating code.
  • User interfaces are hard to test, separation keeps more logic in more testable places.
  • You can easily add a programmatic API for scripting or exposed as services (I actually see these as alternative presentations).
  • Presentation code requires different skills and knowledge to domain code.

Despite these many advantages, I often see this principle violated. I think this is partly due to lack of knowledge, and partly due to the fact that many frameworks make it much too easy to intermix domain logic into the presentation, and make it harder to maintain the separation.

Don't make the mistake that this is a client/server physical separation. Even if all your code is running on the same machine, it's well worth making this logical separation.

This principle is the most prominent part of Model View Controller (MVC), indeed for many people MVC is how they describe this separation.

Remember that such things as web services are also presentations, even though they are used by computer users rather than human users. So don't intermix domain code with the code required to support a web service, or indeed any other external API.

(I also wrote about this in an IEEE Software column .)

presentation domain data

IMAGES

  1. Presentation Domain Data Layering

    presentation domain data

  2. Active domains of data science

    presentation domain data

  3. Enterprise Architecture Domains Business Data Application And

    presentation domain data

  4. PPT

    presentation domain data

  5. How Different Domains Use Data

    presentation domain data

  6. Discovering the Domain Architecture

    presentation domain data

COMMENTS

  1. Presentation Domain Data Layering

    Layering a system into presentation (UI), domain logic, and data access. This layering is useful but should not used for the higher modules of larger systems.

  2. Clean Architecture Guide (with tested examples): Data Flow ...

    Presentation Layer depends on Domain Layer. Domain Layer is the most INNER part of the onion (no dependencies with other layers) and it contains Entities, Use cases & Repository Interfaces. Use cases combine data from 1 or multiple Repository Interfaces. Data Layer contains Repository Implementations and 1 or multiple Data Sources.

  3. Clean Architecture

    The Clean Architecture and the Data Domain Presentation Architecture is pretty popular and I've been asked a lot about it directly and indirectly. I decided to take a Clean Architecture Example ...

  4. Flutter App Architecture: The Presentation Layer

    Flutter App Architecture: The Domain Model. Flutter App Architecture: The Application Layer. And this time, we will focus on the presentation layer and learn how we can use controllers to: hold business logic. manage the widget state. interact with repositories in the data layer. This kind of controller is the same as the view model that you ...

  5. Organizing Presentation Logic

    In an ideal application that uses presentation, domain, and data source layers you'll have domain logic only operating on session state. In practice this distinction gets muddied, usually for bad reasons but sometimes for a good reason.

  6. Separated Presentation

    Ensure that any code that manipulates presentation only manipulates presentation, pushing all domain and data source logic into clearly separated areas of the program.

  7. Clean Architecture

    The Domain Layer could be included in the Application Layer, but if you are using an ORM like entity framework, the Infrastructure Layer will need to reference the domain models, in which case it's better to split out into a separate layer. Data annotations should be left out of domain models.

  8. Multiple ways of defining Clean Architecture layers

    Approach 1 — CA layers in a single module The simplest approach would be to have 3 packages ( presentation, domain, data) inside the app module. This approach works, but it has a few serious flaws.

  9. Clean Architecture with MVVM

    Clean Architecture With MVVM Presentation Layers includes normal activities, fragments, adapters, view models. Domain Layer is a contract between the Data Layer and the Presentation Layer.

  10. A Brief Intro to Clean Architecture, Clean DDD, and CQRS

    A brief explanation of Clean Architecture, Clean Domain-Driven Design, and Command/Query Responsibility Segregation.

  11. Flutter App Architecture: The Domain Model

    Broadly speaking, four different layers are normally identified: Flutter App Architecture using data, domain, application, and presentation layers. The data layer sits at the bottom and contains the repositories that are used to talk to external data sources. Just above it, we find the domain and application layers.

  12. A Template for Clean Domain-Driven Design Architecture

    A software architectural template for applying Clean Domain-Driven Design and CQRS to your own solutions

  13. Why should I isolate my domain entities from my presentation layer?

    One part of domain-driven design that there doesn't seem to be a lot of detail on, is how and why you should isolate your domain model from your interface. I'm trying to convince my colleagues that...

  14. Domain layer

    Domain layer. The domain layer is an optional layer that sits between the UI layer and the data layer. Figure 1. The domain layer's role in app architecture. The domain layer is responsible for encapsulating complex business logic, or simple business logic that is reused by multiple ViewModels. This layer is optional because not all apps will ...

  15. Making a Data Layer that is tightly coupled to the Presentation Layer

    Now, I am confused about how to make the UseCase here because obviously the Presentation Layer and the Data Layer is coupled because they need the CMSampleBuffer to function.

  16. Refactoring Module Dependencies

    Presentation-Domain-Data Layering I said earlier that setting module boundaries was a subtle and nuanced art, but one guideline that many people follow is Presentation-Domain-Data Layering - separating presentation code (UI), business logic, and data access.

  17. Presentation Layer in OSI model

    Introduction : Presentation Layer is the 6th layer in the Open System Interconnection (OSI) model. This layer is also known as Translation layer, as this layer serves as a data translator for the network. The data which this layer receives from the Application Layer is extracted and manipulated here as per the required format to transmit over ...

  18. Presentation Domain Separation

    Presentation logic and domain logic are easier to understand when separate. You can support multiple presentations on the same base program without duplicating code. User interfaces are hard to test, separation keeps more logic in more testable places. You can easily add a programmatic API for scripting or exposed as services (I actually see ...

  19. Five Essential Presenting Tips for Data Professionals

    This can lead to more opportunities and is rightfully seen as a very positive trait for data professionals. Create a Data-Driven Culture: By creating high-quality data presentations you are improving data literacy. After once sitting through a great presentation on IoT devices, I came out of it knowing more about time series in general.

  20. Data Model Powerpoint Templates and Google Slides Themes

    These data model themed PowerPoint templates can enhance your presentations by providing a visually appealing and cohesive design that aligns with the topic. With their modern and professional look, they can help you effectively communicate complex data and concepts, making your presentations more engaging and impactful.

  21. Explaining Purview concepts: Domains, Business Domains, Collections

    A business domain must have a name, a description, a type (Functional Unit, Line of business, Data Domain, Regulatory or Project). "Finance" and "Human Resources" are of type "Functional Unit" and are intended to group data assets discovered from Azure Databases containing several master tables about our clients, contracts, workers ...