15 Nov 2023



Advanced

Examples of factories in Domain Driven Design with java pseudo code:

1. Entity Factory:

public class OrderFactory {
    public Order createOrder(Customer customer, List<OrderItem> items) {
        Order order = new Order();
        order.setCustomer(customer);
        order.setItems(items);
        order.setStatus(OrderStatus.PENDING);
        // Additional business logic or validation
        return order;
    }
}

Explanation:

  • Entity Factory: This factory (OrderFactory) is responsible for creating instances of the Order entity. It initializes the order with a customer, a list of order items, and sets the initial status to OrderStatus.PENDING. Additional business logic or validation specific to order creation can be included.

2. Aggregate Factory:

public class ShoppingCartFactory {
    public ShoppingCart createShoppingCart(Customer customer) {
        ShoppingCart cart = new ShoppingCart();
        cart.setCustomer(customer);
        // Additional initialization logic
        return cart;
    }
}

Explanation:

  • Aggregate Factory: In this case (ShoppingCartFactory), the factory is responsible for creating instances of the ShoppingCart aggregate. It sets the customer for the shopping cart and may include additional initialization logic based on the requirements.

3. Value Object Factory:

public class MoneyFactory {
    public Money createMoney(double amount, Currency currency) {
        // Validation logic for amount and currency
        return new Money(amount, currency);
    }
}

Explanation:

  • Value Object Factory: The MoneyFactory is responsible for creating instances of the Money value object. It includes validation logic for the amount and currency, ensuring that the created Money object is valid according to the business rules.

4. Factory for Aggregate with Invariants:

public class LoanApplicationFactory {
    public LoanApplication createLoanApplication(Applicant applicant, Money requestedAmount) {
        // Additional validation or business rules
        if (applicant.isEligibleForLoan(requestedAmount)) {
            return new LoanApplication(applicant, requestedAmount);
        } else {
            throw new InvalidLoanApplicationException("Applicant is not eligible for the requested loan amount.");
        }
    }
}

Explanation:

  • Factory for Aggregate with Invariants: The LoanApplicationFactory creates instances of the LoanApplication aggregate. It incorporates additional validation or business rules (isEligibleForLoan) to ensure that the created loan application is valid. If the validation fails, it throws an exception.

5. Factory for Complex Aggregate:

public class ConferenceFactory {
    public Conference createConference(String name, LocalDate startDate, LocalDate endDate, List<Session> sessions) {
        // Validation and business rules for conference creation
        if (startDate.isBefore(endDate) && !sessions.isEmpty()) {
            Conference conference = new Conference(name, startDate, endDate);
            conference.setSessions(sessions);
            return conference;
        } else {
            throw new InvalidConferenceException("Invalid conference parameters");
        }
    }
}

Explanation:

  • Factory for Complex Aggregate: The ConferenceFactory is responsible for creating instances of the Conference aggregate. It includes validation and business rules, checking if the start date is before the end date and ensuring that there are sessions associated with the conference. If the validation fails, it throws an exception.

6. Factory for User Registration:

public class UserFactory {
    public User registerUser(String username, String email, String password) {
        // Validate username, email, and password
        if (isValidUsername(username) && isValidEmail(email) && isValidPassword(password)) {
            User user = new User(username, email, password);
            // Additional user registration logic
            return user;
        } else {
            throw new InvalidUserRegistrationException("Invalid user registration details");
        }
    }

    private boolean isValidUsername(String username) {
        // Validation logic for username
        return /* validation logic */;
    }

    private boolean isValidEmail(String email) {
        // Validation logic for email
        return /* validation logic */;
    }

    private boolean isValidPassword(String password) {
        // Validation logic for password
        return /* validation logic */;
    }
}

Explanation:

  • User Registration Factory: The UserFactory creates instances of the User entity for user registration. It includes validation logic for the username, email, and password. If the provided details are valid, it creates a new user; otherwise, it throws an exception.

7. Factory for Product Creation:

public class ProductFactory {
    public Product createProduct(String name, Money price, Category category) {
        // Validation logic for product creation
        if (isValidProductName(name) && isValidProductPrice(price) && isValidProductCategory(category)) {
            return new Product(name, price, category);
        } else {
            throw new InvalidProductCreationException("Invalid product details");
        }
    }

    private boolean isValidProductName(String name) {
        // Validation logic for product name
        return /* validation logic */;
    }

    private boolean isValidProductPrice(Money price) {
        // Validation logic for product price
        return /* validation logic */;
    }

    private boolean isValidProductCategory(Category category) {
        // Validation logic for product category
        return /* validation logic */;
    }
}

Explanation:

  • Product Creation Factory: The ProductFactory creates instances of the Product entity. It includes validation logic for the product name, price, and category. If the provided details are valid, it creates a new product; otherwise, it throws an exception.

8. Factory for Address Creation:

public class AddressFactory {
    public Address createAddress(String street, String city, String zipCode, Country country) {
        // Validation logic for address creation
        if (isValidStreet(street) && isValidCity(city) && isValidZipCode(zipCode) && isValidCountry(country)) {
            return new Address(street, city, zipCode, country);
        } else {
            throw new InvalidAddressCreationException("Invalid address details");
        }
    }

    private boolean isValidStreet(String street) {
        // Validation logic for street
        return /* validation logic */;
    }

    private boolean isValidCity(String city) {
        // Validation logic for city
        return /* validation logic */;
    }

    private boolean isValidZipCode(String zipCode) {
        // Validation logic for zip code
        return /* validation logic */;
    }

    private boolean isValidCountry(Country country) {
        // Validation logic for country
        return /* validation logic */;
    }
}

Explanation:

  • Address Creation Factory: The AddressFactory creates instances of the Address value object. It includes validation logic for the street, city, zip code, and country. If the provided details are valid, it creates a new address; otherwise, it throws an exception.

9. Factory for Booking Reservations:

public class ReservationFactory {
    public Reservation bookReservation(Customer customer, Event event, LocalDateTime startTime, LocalDateTime endTime) {
        // Validation logic for reservation booking
        if (isValidReservation(customer, event, startTime, endTime)) {
            return new Reservation(customer, event, startTime, endTime);
        } else {
            throw new InvalidReservationException("Invalid reservation details");
        }
    }

    private boolean isValidReservation(Customer customer, Event event, LocalDateTime startTime, LocalDateTime endTime) {
        // Validation logic for reservation details
        return /* validation logic */;
    }
}

Explanation:

  • Reservation Booking Factory: The ReservationFactory creates instances of the Reservation entity. It includes validation logic for the customer, event, and reservation timing. If the provided details are valid, it creates a new reservation; otherwise, it throws an exception.

10. Factory for Employee Onboarding:

public class EmployeeFactory {
    public Employee onboardEmployee(String name, String position, LocalDate hireDate) {
        // Validation logic for employee onboarding
        if (isValidEmployeeName(name) && isValidPosition(position) && isValidHireDate(hireDate)) {
            return new Employee(name, position, hireDate);
        } else {
            throw new InvalidEmployeeOnboardingException("Invalid employee onboarding details");
        }
    }

    private boolean isValidEmployeeName(String name) {
        // Validation logic for employee name
        return /* validation logic */;
    }

    private boolean isValidPosition(String position) {
        // Validation logic for employee position
        return /* validation logic */;
    }

    private boolean isValidHireDate(LocalDate hireDate) {
        // Validation logic for employee hire date
        return /* validation logic */;
    }
}

Explanation:

  • Employee Onboarding Factory: The EmployeeFactory creates instances of the Employee entity for employee onboarding. It includes validation logic for the employee name, position, and hire date. If the provided details are valid, it creates a new employee; otherwise, it throws an exception.

These examples demonstrate the versatility of factories in handling the creation of various domain objects in a domain-driven design. The factories encapsulate the creation logic and enforce domain-specific validation rules.

Note📌: Above pseudo-code snippets illustrate the factories in DDD. In a real-world scenario, you would likely have more sophisticated implementations and considerations.

domain-driven-design-ddd
factories
examples