Domain
and Entity
mismatch over time is a problem in OOP designed system.
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
Renders the user interface
of a software application.
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.
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.
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.
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.
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.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.
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.
domain object
belongs to a Repository
.Entities
What the system stores.
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.
anemic
(no methods
except getters
and setters
).Domain Objects
public class CustomerEntity { private Long customerId; private String name; private String email; // Getters, Setters }
Business Objects
)BOs represent real world entities
(plural) in the business domain with its behaviors.
Customer
, User
, Invoices
customer.placeOrder()
, user.signIn()
.BO are not just data, but also the behavior of the business domain.
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; } }
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
.
getById()
Interface between your Service
layer and the actual persistence mechanism
.
DAOs
usually don't define database transactions, they let the service
do that.
Responsible for storing and retrieving data from a permanent storage system.
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.
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; } }