HomeToolsAbout

Domain Driven Design

Challenge in an OOP system

Domain and Entity mismatch over time is a problem in OOP designed system.

  • Definitions could drift as the application and its logic grows.

Domain = What the system is about. Entity = What the system stores.

View layer <<(HTTP)>> Controller layer <<(DTOs)>> Service Layer <<(DTOs)>> Domain Layer/Domain <<(DAO)>> Persistence Mechanism

Presentation/View Layer

Renders the user interface of a software application.

  • Provides a visual representation of the application’s data and functionality.
  • End user interacts with this layer directly
  • It is responsible for displaying data and receiving input from the user.

Example: Web

Interface between user's browser and service layer.

Converts HTTP parameters into data the service layer would need.

Controller Layer

It provides a set of endpoints or URLs that map to specific actions or methods in the application, allowing the user to interact with the application via HTTP requests.

Calls the service layer.

Purpose of the controller layer is to provide a centralized point of control for the application, allowing developers to separate the concerns of user interface and business logic.

It also provides a layer of abstraction between the view layer and the business logic layer, making it easier to modify or replace either layer without affecting the other.

DTO (Data Transfer Objects).

DTOs transfer data between processes or network boundaries.

  • Its primary role is to encapsulate and carry data, reducing the number of method calls and simplifying the transportation of data.

DTOs are typically serialized to XML, JSON, or binary format.

DTOs can exist between client and service or among services or between service and storage layer.

  • e.g. what is used to communicate between view layer and the service layer.

DTOs should not contain any business logic.

DTOs are lightweight (efficient transfer across network) and prevents exposure of sensitive information.

  • Separates the underlying database or business model from the consumer, ensuring that internal representations (e.g., entities) are not exposed outside their respective layers.

Service Layer (Application/Business Logic Layer)

A Service is something that performs some task.

  • All business logic lives in the service layer.

The service layer contains the application’s core logic and provides a set of methods or functions that can be used by the presentation layer to perform specific tasks or operations.

Different use cases usually don't break down cleanly along entity lines.

  • Service involve dependencies that entities try to avoid.
  • Domain model is about modeling state and changes to state, and the dependencies are about infrastructure.

The service layer orchestrates interactions between different components, including the domain layer, infrastructure, and other external systems.

The service layer also helps to improve the testability of the application by allowing for unit testing of the business logic without the need for the presentation layer.

// interface for presentation public interface BlogManager { Blog load(String name) throws EntityNotFoundException; } // consistent interface service class public class BlogManagerService implements BlogManager { // Fictitious EntityManager EntityManager em; // class method to interact with the DB public Blog load(String name) throws EntityNotFoundException { Blog blog = null; BlogData data = em.query("select b from BlogData b where b.name = ?", name); return new Blog(data); } }

Application (service) Layer vs Domain Layer

All logic concerning the application workflow typically end up being Application Services factored into the Application Layer.

Whereas concepts from the domain that don’t seem to fit as model objects end up forming one or more Domain Services.

Domain Layer (Domain Model)

Represents core logic and behavior of a single type of entities (domain objects).

Independent of any specific implementation details such as user interfaces, databases, or external systems.

It contains the business rules, entities, and operations that are specific to the problem domain being addressed by the application.

  • It encapsulates the application’s domain-specific knowledge.
class Order: def __init__(self): self.items = [] def add_item(self, product: Product, quantity: int): order_item = OrderItem(product, quantity) self.items.append(order_item) def calculate_total(self): return sum(item.get_item_total() for item in self.items) def validate(self): if not self.items: raise ValueError("Order must contain at least one item") # usage order = Order() order.add_item(product_1, quantity=1)

Domain Object vs Domain Logic

  • Domain Objects are objects for storing data.
  • Domain Logic/Services are objects that manipulate Domain Objects.

Separation of Domain Objects and Domain Services is not really OO since OO is to put functionality together with data.

This layer is typically made up of entities, value objects, aggregates, and repositories that encapsulate the behavior and state of the application.

  • CRUD operations on domain object belongs to a Repository.

Entities

What the system stores.

  • Entities represent data persistence and identity.
  • e.g. Employee, Product, Order

Usually an Entity class ends up getting mapped to a database table.

In some cases (DDD) there are rich domain models where entities have methods that can manipulate the model's state.

  • Some make them anemic (no methods except getters and setters).
  • Domain Objects
public class CustomerEntity { private Long customerId; private String name; private String email; // Getters, Setters }

BO (Business Objects)

BOs represent real world entities (plural) in the business domain with its behaviors.

  • Encapsulate both data and rules/behaviors relevant to the domain.
  • e.g. Customer, User, Invoices
    • Methods on BO would be customer.placeOrder(), user.signIn().

BO are not just data, but also the behavior of the business domain.

  • encapsulates both state (data) and behavior (methods).
  • BOs contain business logic.

BO can exist in the service or domain layer of an application.

public class CustomerBO { private CustomerEntity customerEntity; public CustomerBO(CustomerEntity customerEntity) { this.customerEntity = customerEntity; } public void placeOrder(Order order) { // Logic to place an order } public int calculateLoyaltyPoints() { // Business logic to calculate loyalty points return 100; } }

Persistence/Storage Layer

DAO (Data Access Objects)

A Data Access Object (DAOs) provides a way to query or update data, it could have query methods that would return an entity or collection of entities.

  • e.g. getById()

Interface between your Service layer and the actual persistence mechanism.

DAOs usually don't define database transactions, they let the service do that.

Persistence Layer

Responsible for storing and retrieving data from a permanent storage system.

  • database, file system, or message queue.

It provides an interface between the application’s business logic layer and the underlying data storage layer.

The persistence layer is typically implemented using an object-relational mapping (ORM) tool.

  • maps the application’s domain objects to the database tables and performs CRUD operations.

The purpose of the persistence layer is to abstract the underlying data storage layer from the application’s business logic layer, providing a standardized interface for data access that is independent of the specific storage technology used. This allows for easier maintenance and modification of the application, as well as increased scalability and flexibility.

@Persistent public class BlogData { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
AboutContact