Skip to content

Instantly share code, notes, and snippets.

@gbzarelli
Last active November 21, 2023 18:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gbzarelli/0cda06305696a8dab724c0b881062f25 to your computer and use it in GitHub Desktop.
Save gbzarelli/0cda06305696a8dab724c0b881062f25 to your computer and use it in GitHub Desktop.
Domain model - Rich Sample
// Remoção nas notações globais do Lombook, deixando-as específicas e garantindo mais imutablidade para o domínio
public class Order {
// Considere a criação de objetos usando static factory
//Static factory para a criação de uma nova Order:
public static Order create(final OrderId orderId, final List<Product> items, final BigDecimal orderAmount) {
return new Order(orderId, items, null, orderAmount);
}
//Static factory para a criação de uma Order com pagamento:
public static Order from(final Order order, final Payment payment) {
return new Order(order.id, order.items, payment, order.orderAmount);
}
@Getter
private final OrderId id;
private final List<Product> items;
private final Payment payment;
@Getter
private final BigDecimal orderAmount;
// Contrutor privado, restringindo a construção via static factory, e validando as entradas.
private Order(final OrderId id, final List<Product> items, final Payment payment, final BigDecimal orderAmount) {
this.id = Objects.requireNonNull(id, "OrderId can't be null");
if (items == null || items.isEmpty()) {
throw new IllegalArgumentException("Items can't be empty or null");
} else {
this.items = items;
}
this.payment = payment;
if (orderAmount == null || orderAmount.compareTo(BigDecimal.ZERO) <= 0) {
throw new IllegalArgumentException("Order cannot have a value less than or equal to zero");
}
this.orderAmount = orderAmount;
}
// Adicionando um pagamento e mantendo a imutabilidade:
public Order addPayment(final Payment payment){
if(isAlreadyPaid()){
throw new AlreadyOrderPaymentException("Payment already exists in order");
}
return Order.from(this, payment);
}
public boolean isAlreadyPaid() {
return getPayment().isPresent() && payment.getAmount().compareTo(orderAmount) == 0;
}
public Optional<Payment> getPayment() {
return Optional.ofNullable(payment);
}
public List<Product> getItems() {
//Para evitar a modificação fora do domínio.
return Collections.unmodifiableList(items);
}
}
@Getter
public class OrderId {
public static OrderId valueOf(final String orderId) {
return new OrderId(orderId);
}
private final String value;
private OrderId(final String value) {
this.value = Objects.requireNonNull(value);
if(value.length() < 10 || value.length() > 20){
// O que define um orderId? Podemos ter regras e validações específicas de negócio.
throw new IllegalArgumentException("Invalid orderId");
}
}
}
@AllArgsConstructor
public class OrderService {
private final OrderRepository orderRepository;
public Payment payOrder(final OrderId orderId, final Payment payment){
final var currentOrder = orderRepository.getOrder(orderId);
final var orderPaid = currentOrder.addPayment(payment);
return orderRepository.saveOrderPayment(orderPaid);
}
}
public class Payment {
public static Payment create(final PaymentId paymentId, final BigDecimal amount, final LocalDateTime paymentDateTime) {
return new Payment(paymentId, amount, paymentDateTime);
}
public static Payment create(final BigDecimal amount, final LocalDateTime paymentDateTime) {
return new Payment(PaymentId.NOT_REGISTERED, amount, paymentDateTime);
}
@Getter
private final PaymentId paymentId;
@Getter
private final BigDecimal amount;
@Getter
private final LocalDateTime paymentDateTime;
private Payment(final PaymentId paymentId, final BigDecimal amount, final LocalDateTime paymentDateTime) {
this.paymentId = paymentId;
if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) {
throw new IllegalArgumentException("Payment cannot have a value less than or equal to zero");
}
this.amount = amount;
if (paymentDateTime == null || paymentDateTime.isAfter(LocalDateTime.now())) {
throw new IllegalArgumentException("The payment date can't be after now or null");
}
this.paymentDateTime = paymentDateTime;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment