# Mapping entity objects to domain interface
Canonical: https://social-archive.org/arc/ccdWcfbg70
Original URL: https://stackoverflow.com/questions/79965259/mapping-entity-objects-to-domain-interface
Author: F.M, Marc Le Bihan, Torben, peter8015
Platform: web
Share mode: full
## Content
3 I have an interface in domain and two string infrastructure that represent that interface. the problem is, the interface cannot initiate in mapper class so I don't know how to map entity to domain in manual mapping. I started learning senior coding so I shouldn't use switch and should consider solid concepts. The codes I wrote: OrderDiscount is an interface in domain discountType, discountValue are in database. These feilds should map to orderDiscount domain: ``` private Order(String id, String customerId, List items, Money totalPrice, OrderDiscount discount, OrderStatus status, LocalDateTime createdAt, LocalDateTime updatedAt ) public static Order create(String customerId, List items, OrderDiscount discount){ LocalDateTime now = LocalDateTime.now(); Money finalPrice = calculateFinalPrice(items, discount); return new Order( UUID.randomUUID().toString(), customerId, items, finalPrice, discount, OrderStatus.PENDING, now, now); } ``` ``` public interface OrderDiscount { Money applyTo(Money total); OrderDiscountDetail getDetails(); DiscountType type(); } ``` ``` public interface OrderDiscountFactory { DiscountType supportedType(); OrderDiscount create(OrderDiscountDetail detail,Currency currency); } ``` ``` public final class FixedAmountDiscount implements OrderDiscount { private final Money fixedAmountDiscount; private FixedAmountDiscount(Money fixedAmountDiscount) { if (fixedAmountDiscount == null) { throw new IllegalArgumentException( "Flat Discount cannot be null" ); } if (fixedAmountDiscount.getAmount().compareTo(BigDecimal.ZERO) factories; public DiscountRegistry(List factories) { this.factories = factories.stream() .collect(Collectors.toMap( OrderDiscountFactory::supportedType, Function.identity())); } public OrderDiscount create(OrderDiscountDetail detail, Currency currency) { return factories .get(detail.type()) .create(detail, currency); } } ``` ``` public class FixedAmountDiscountFactory implements OrderDiscountFactory { private final DiscountRegistry registry; public FixedAmountDiscountFactory(DiscountRegistry registry) { this.registry = registry; } @Override public DiscountType supportedType() { return DiscountType.FIXED_AMOUNT; } @Override public OrderDiscount create(OrderDiscountDetail detail, Currency currency) { return registry.create(detail, currency); } } ``` infrastructure/entity: ``` @Getter @Enumerated(EnumType.STRING) @Column(name = "discount_type", nullable = false, length = 30) @NotNull(message = "discount type is required") private DiscountType discountType = DiscountType.NONE; @Getter @Column(name = "discount_value", nullable = false, precision = 19, scale = 2) @NotNull(message = "discount value is required") private BigDecimal discountValue = BigDecimal.ZERO; ``` The orderMapper I wrote: ``` public class OrderMapper { private final OrderDiscountFactory discountFactory; public OrderMapper(OrderDiscountFactory discountFactory) { this.discountFactory = discountFactory; } public static OrderEntity toEntity(Order order) { OrderDiscountDetail discountDetail = order.getDiscount().getDetails(); OrderEntity entity = new OrderEntity( order.getId(), order.getCustomerId(), order.getTotalPrice().getAmount(), CurrencyMapper.toEntity( order.getTotalPrice().getCurrency() ), order.getStatus(), discountDetail.type(), discountDetail.value() ); for (OrderItem orderItem : order.getItems()) { entity.addItem(toItemEntity(orderItem)); } return entity; } private static OrderItemEntity toItemEntity(OrderItem item) { return new OrderItemEntity( item.getProductId(), item.getProductName(), item.getQuantity(), item.getPrice().getAmount(), CurrencyMapper.toEntity(item.getPrice().getCurrency())); } public Order toDomain(OrderEntity entity) { Currency currency = Currency.getInstance(entity.getCurrency()); Money money = Money.create(entity.getTotalAmount(), currency); OrderDiscountDetail detail = new OrderDiscountDetail( entity.getDiscountType(), entity.getDiscountValue() ); OrderDiscount discount = discountFactory.create(detail, currency); List items = entity.getItems() .stream() .map(OrderItemMapper::toDomain) .toList(); return Order.restore( entity.getId(), entity.getCustomerId(), items, money, discount, entity.getStatus(), entity.getCreatedAt(), entity.getUpdatedAt() ); } } ``` I found this mapper is bad because the mapper becomes domain-dependent. Please give me the enterprise level answer. I meanthe senior code. [edited Jun 22 at 18:08](https://stackoverflow.com/posts/79965259/revisions) [Arianna Angeletti](https://stackoverflow.com/users/2493678/arianna-angeletti) 118 1 silver badge11 bronze badges asked Jun 22 at 11:56 [F.M](https://stackoverflow.com/users/3567690/f-m) 551 2 gold badges9 silver badges22 bronze badges 5 0 I think the domain interface should remains pure. 'OrderDetail' belongs to Order domain: ``` public interface OrderDiscount { Money applyTo(Money total); DiscountType type(); } ``` answered Jun 22 at 15:29 [peter8015](https://stackoverflow.com/users/2269722/peter8015) 41 7 bronze badges ## 1 Comment Start asking to get answers Find the answer to your question by asking.
## Media
1. image: https://social-archiver-api.social-archive.org/media/archives/arc/L4CrB8plNF/media/0.png
