* update yaml frontmatter format * update abstract document * update abstract factory * use the new pattern template * acyclic visitor seo * adapter seo * ambassador seo * acl seo * aaa seo * async method invocation seo * balking seo * bridge seo * builder seo * business delegate and bytecode seo * caching seo * callback seo * chain seo * update headings * circuit breaker seo * client session + collecting parameter seo * collection pipeline seo * combinator SEO * command seo * cqrs seo * commander seo * component seo * composite seo * composite entity seo * composite view seo * context object seo * converter seo * crtp seo * currying seo * dao seo * data bus seo * data locality seo * data mapper seo * dto seo * decorator seo * delegation seo * di seo * dirty flag seo * domain model seo * double buffer seo * double checked locking seo * double dispatch seo * dynamic proxy seo * event aggregator seo * event-based asynchronous seo * eda seo * event queue seo * event sourcing seo * execute around seo * extension objects seo * facade seo * factory seo * factory kit seo * factory method seo * fanout/fanin seo * feature toggle seo * filterer seo * fluent interface seo * flux seo * flyweight seo * front controller seo * function composition seo * game loop seo * gateway seo * guarded suspension seo * half-sync/half-async seo * health check seo * hexagonal seo * identity map seo * intercepting filter seo * interpreter seo * iterator seo * layers seo * lazy loading seo * leader election seo * leader/followers seo * lockable object seo * rename and add seo for marker interface * master-worker seo * mediator seo * memento seo * metadata mapping seo * microservice aggregator seo * api gw seo * microservices log aggregration seo * mvc seo * mvi seo * mvp seo * mvvm seo * monad seo * monitor seo * monostate seo * multiton seo * mute idiom seo * naked objects & notification seo * null object seo * object mother seo * object pool seo * observer seo * optimistic locking seo * page controller seo * page object seo * parameter object seo * partial response seo * pipeline seo * poison pill seo * presentation model seo * private class data seo * producer-consumer seo * promise seo * property seo * prototype seo * proxy seo * queue-based load leveling seo * reactor seo * registry seo * repository seo * RAII seo * retry seo * role object seo * saga seo * separated interface seo * serialized entity seo * serialized lob seo * servant seo * server session seo * service layer seo * service locator seo * service to worker seo * sharding seo * single table inheritance seo * singleton seo * spatial partition seo * special case seo * specification seo * state seo * step builder seo * strangler seo * strategy seo * subclass sandbox seo * table module seo * template method seo * throttling seo * tolerant reader seo * trampoline seo * transaction script seo * twin seo * type object seo * unit of work seo * update method seo * value object seo * version number seo * virtual proxy seo * visitor seo * seo enhancements * seo improvements * SEO enhancements * SEO improvements * SEO additions * SEO improvements * more SEO improvements * rename hexagonal + SEO improvements * SEO improvements * more SEO stuff * SEO improvements * SEO optimizations * SEO enhancements * enchance SEO * improve SEO * SEO improvements * update headers
12 KiB
title, shortTitle, description, category, language, tag
| title | shortTitle | description | category | language | tag | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Domain Model Pattern in Java: Building Robust Business Logic | Domain Model | Learn about the Domain Model pattern in Java design with detailed explanations, examples, and applications. Improve your software's modularity, maintainability, and scalability. | Structural | en |
|
Also known as
- Conceptual Model
- Domain Object Model
Intent of Domain Model Design Pattern
The Domain Model pattern aims to create a conceptual model in your software that matches the real-world system it's designed to represent. It involves using rich domain objects that encapsulate both data and behavior relevant to the application domain, ensuring business logic is centralized.
Detailed Explanation of Domain Model Pattern with Real-World Examples
Real-world example
Consider an online bookstore system that uses the Domain Model design pattern. In this system, various domain objects such as
Book,Author,Customer, andOrderencapsulate the core business logic and rules. For instance, theBookobject contains attributes like title, author, price, and stock quantity, along with methods to manage these attributes. TheOrderobject manages order details, calculates the total price, and verifies stock availability. This approach ensures that the business logic is centralized within the domain objects, making the system more modular, easier to maintain, and scalable as new features are added.
In plain words
The Domain Model is an object model of the domain that incorporates both behavior and data.
Programmatic Example of Domain Model Pattern in Java
Let's assume that we need to build an e-commerce web application. While analyzing requirements you will notice that there are few nouns you talk about repeatedly. It’s your Customer, and a Product the customer looks for. These two are your domain-specific classes and each of that classes will include some business logic specific to its domain.
In the example of the e-commerce app, we need to deal with the domain logic of customers who want to buy products and return them if they want. We can use the domain model pattern and create classes Customer and Product where every single instance of that class incorporates both behavior and data and represents only one record in the underlying table.
public class Customer {
// Customer properties and methods
}
public class Product {
// Product properties and methods
}
Data Access Objects (DAOs): These objects provide an abstract interface to the database. They are used to retrieve domain entities and save changes back to the database. In the provided code, CustomerDaoImpl and ProductDaoImpl are the DAOs.
public class CustomerDaoImpl implements CustomerDao {
// Implementation of the methods defined in the CustomerDao interface
}
public class ProductDaoImpl implements ProductDao {
// Implementation of the methods defined in the ProductDao interface
}
Domain Logic: This is encapsulated within the domain entities. For example, the Customer class has methods like buyProduct and returnProduct which represent the actions a customer can perform.
public class Customer {
// Other properties and methods...
public void buyProduct(Product product) {
// Implementation of buying a product
}
public void returnProduct(Product product) {
// Implementation of returning a product
}
}
Application: The App class uses the domain entities and their methods to implement the business logic of the application.
public class App {
public static final String H2_DB_URL = "jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1";
public static final String CREATE_SCHEMA_SQL =
"CREATE TABLE CUSTOMERS (name varchar primary key, money decimal);"
+ "CREATE TABLE PRODUCTS (name varchar primary key, price decimal, expiration_date date);"
+ "CREATE TABLE PURCHASES ("
+ "product_name varchar references PRODUCTS(name),"
+ "customer_name varchar references CUSTOMERS(name));";
public static final String DELETE_SCHEMA_SQL =
"DROP TABLE PURCHASES IF EXISTS;"
+ "DROP TABLE CUSTOMERS IF EXISTS;"
+ "DROP TABLE PRODUCTS IF EXISTS;";
public static void main(String[] args) throws Exception {
// Create data source and create the customers, products and purchases tables
final var dataSource = createDataSource();
deleteSchema(dataSource);
createSchema(dataSource);
// create customer
var customerDao = new CustomerDaoImpl(dataSource);
var tom =
Customer.builder()
.name("Tom")
.money(Money.of(USD, 30))
.customerDao(customerDao)
.build();
tom.save();
// create products
var productDao = new ProductDaoImpl(dataSource);
var eggs =
Product.builder()
.name("Eggs")
.price(Money.of(USD, 10.0))
.expirationDate(LocalDate.now().plusDays(7))
.productDao(productDao)
.build();
var butter =
Product.builder()
.name("Butter")
.price(Money.of(USD, 20.00))
.expirationDate(LocalDate.now().plusDays(9))
.productDao(productDao)
.build();
var cheese =
Product.builder()
.name("Cheese")
.price(Money.of(USD, 25.0))
.expirationDate(LocalDate.now().plusDays(2))
.productDao(productDao)
.build();
eggs.save();
butter.save();
cheese.save();
// show money balance of customer after each purchase
tom.showBalance();
tom.showPurchases();
// buy eggs
tom.buyProduct(eggs);
tom.showBalance();
// buy butter
tom.buyProduct(butter);
tom.showBalance();
// trying to buy cheese, but receive a refusal
// because he didn't have enough money
tom.buyProduct(cheese);
tom.showBalance();
// return butter and get money back
tom.returnProduct(butter);
tom.showBalance();
// Tom can buy cheese now because he has enough money
// and there is a discount on cheese because it expires in 2 days
tom.buyProduct(cheese);
tom.save();
// show money balance and purchases after shopping
tom.showBalance();
tom.showPurchases();
}
private static DataSource createDataSource() {
var dataSource = new JdbcDataSource();
dataSource.setUrl(H2_DB_URL);
return dataSource;
}
private static void deleteSchema(DataSource dataSource) throws SQLException {
try (var connection = dataSource.getConnection();
var statement = connection.createStatement()) {
statement.execute(DELETE_SCHEMA_SQL);
}
}
private static void createSchema(DataSource dataSource) throws SQLException {
try (var connection = dataSource.getConnection();
var statement = connection.createStatement()) {
statement.execute(CREATE_SCHEMA_SQL);
}
}
}
The program output:
12:17:23.834 [main] INFO com.iluwatar.domainmodel.Customer -- Tom balance: USD 30.00
12:17:23.836 [main] INFO com.iluwatar.domainmodel.Customer -- Tom didn't bought anything
12:17:23.841 [main] INFO com.iluwatar.domainmodel.Customer -- Tom want to buy Eggs($10,00)...
12:17:23.842 [main] INFO com.iluwatar.domainmodel.Customer -- Tom bought Eggs!
12:17:23.842 [main] INFO com.iluwatar.domainmodel.Customer -- Tom balance: USD 20.00
12:17:23.842 [main] INFO com.iluwatar.domainmodel.Customer -- Tom want to buy Butter($20,00)...
12:17:23.843 [main] INFO com.iluwatar.domainmodel.Customer -- Tom bought Butter!
12:17:23.843 [main] INFO com.iluwatar.domainmodel.Customer -- Tom balance: USD 0.00
12:17:23.843 [main] INFO com.iluwatar.domainmodel.Customer -- Tom want to buy Cheese($20,00)...
12:17:23.843 [main] ERROR com.iluwatar.domainmodel.Customer -- Not enough money!
12:17:23.843 [main] INFO com.iluwatar.domainmodel.Customer -- Tom balance: USD 0.00
12:17:23.843 [main] INFO com.iluwatar.domainmodel.Customer -- Tom want to return Butter($20,00)...
12:17:23.844 [main] INFO com.iluwatar.domainmodel.Customer -- Tom returned Butter!
12:17:23.844 [main] INFO com.iluwatar.domainmodel.Customer -- Tom balance: USD 20.00
12:17:23.844 [main] INFO com.iluwatar.domainmodel.Customer -- Tom want to buy Cheese($20,00)...
12:17:23.844 [main] INFO com.iluwatar.domainmodel.Customer -- Tom bought Cheese!
12:17:23.846 [main] INFO com.iluwatar.domainmodel.Customer -- Tom balance: USD 0.00
12:17:23.846 [main] INFO com.iluwatar.domainmodel.Customer -- Tom bought: Eggs - $10.00, Cheese - $20.00
Detailed Explanation of Domain Model Pattern with Real-World Examples
When to Use the Domain Model Pattern in Java
- Appropriate in complex applications with rich business logic.
- When the business logic or domain complexity is high and requires a model that closely represents real-world entities and their relationships.
- Suitable for applications where domain experts are involved in the development process to ensure the model accurately reflects domain concepts.
Domain Model Pattern Java Tutorials
Real-World Applications of Domain Model Pattern in Java
- Enterprise applications (ERP, CRM systems)
- Financial systems (banking, trading platforms)
- Healthcare applications (patient records management)
- E-commerce platforms (product catalogs, shopping carts)
Benefits and Trade-offs of Domain Model Pattern
Benefits:
- Improved Communication: Provides a common language for developers and domain experts, enhancing understanding and collaboration.
- Flexibility: Encapsulates business logic within domain entities, making it easier to modify and extend without affecting other system parts.
- Maintainability: A well-structured domain model can simplify maintenance and evolution of the application over time.
- Reusability: Domain classes can often be reused across different projects within the same domain.
Trade-offs:
- Complexity: Can introduce complexity, especially in simple applications where a domain model might be overkill.
- Performance Concerns: Rich domain objects with complex behaviors might lead to performance bottlenecks, requiring careful optimization.
- Learning Curve: Requires a good understanding of the domain and may involve a steep learning curve for developers unfamiliar with the domain concepts.
Related Java Design Patterns
- Data Access Object (DAO): For abstracting and encapsulating all access to the data source.
- Repository: Mediates between the domain and data mapping layers, acting like an in-memory domain object collection.
- Service Layer: Defines an application's boundary with a layer of services that establishes a set of available operations and coordinates the application's response in each operation.
- Unit of Work: Maintains a list of objects affected by a business transaction and coordinates the writing out of changes.
