設計と設計発注と割引ドメイン


オーダーと割引ドメインの設計


注文および割引ポリシー

  • 会員は商品を注文することができます.
  • 会員等級によって割引政策が適用されます.
  • 割引政策は、すべてのVIPに1000元の固定金額割引があります.(変更可能)
  • 割引政策が変わる可能性が高い.会社の基本的な割引政策はまだ確定していないので、開業前に延期したいという悩み.最悪の場合は割引が適用されない可能性があります.(保留中)
  • 受注生成:クライアントは受注サービスに受注の生成を要求します.
  • 照会
  • 会員:割引には会員等級が必要です.そのため、注文サービスは会員リポジトリで会員を検索します.
  • 割引が適用されます.注文サービスは会員等級に基づいて割引ポリシーを許可します.
  • は、受注結果を返します.受注サービスは、割引結果を含む受注結果を返します.




  • 割引ポリシーインタフェース

    package hello.core.discount;
    import hello.core.member.Member;
    public interface DiscountPolicy {
    
        /**
         * @return 할인 대상 금액
         */
        int discount(Member member, int price);
    }

    固定割引政策実施体

    package hello.core.discount;
    
    import hello.core.member.Grade;
    import hello.core.member.Member;
    
    public class FixDiscountPolicy implements DiscountPolicy {
    
        private int discountFixAmount = 1000; // 1000원 할인
    
        @Override
        public int discount(Member member, int price) {
    
            if (member.getGrade() == Grade.VIP) {
                return discountFixAmount;
            } else {
                return 0;
            }
        }
    }
    

    受注エンティティ

    package hello.core.order;
    
    public class Order {
    
        private Long memberId;
        private String itemName;
        private int itemPrice;
        private int discountPrice;
    
        public Order(Long memberId, String itemName, int itemPrice, int discountPrice) {
            this.memberId = memberId;
            this.itemName = itemName;
            this.itemPrice = itemPrice;
            this.discountPrice = discountPrice;
        }
    
        //비즈니스 로직
        public int calculatePrice() {
            return itemPrice - discountPrice;
        }
    
        public Long getMemberId() {
            return memberId;
        }
    
        public void setMemberId(Long memberId) {
            this.memberId = memberId;
        }
    
        public String getItemName() {
            return itemName;
        }
    
        public void setItemName(String itemName) {
            this.itemName = itemName;
        }
    
        public int getItemPrice() {
            return itemPrice;
        }
    
        public void setItemPrice(int itemPrice) {
            this.itemPrice = itemPrice;
        }
    
        public int getDiscountPrice() {
            return discountPrice;
        }
    
        public void setDiscountPrice(int discountPrice) {
            this.discountPrice = discountPrice;
        }
    
        @Override
        public String toString() {
            return "Order{" +
                    "memberId=" + memberId +
                    ", itemName='" + itemName + '\'' +
                    ", itemPrice=" + itemPrice +
                    ", discountPrice=" + discountPrice +
                    '}';
        }
    }
    

    オーダーサービスインタフェース

    package hello.core.order;
    
    public interface OrderService {
    
        Order createOrder(Long memberId, String itemName, int itemPrice);
    }

    オーダーサービス実施機関

    package hello.core.order;
    
    import hello.core.discount.DiscountPolicy;
    import hello.core.discount.FixDiscountPolicy;
    import hello.core.member.Member;
    import hello.core.member.MemberRepository;
    import hello.core.member.MemoryMemberRepository;
    
    public class OrderServiceImpl implements OrderService {
    
        private final MemberRepository memberRepository = new MemoryMemberRepository();
        private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
    
    
        @Override
        public Order createOrder(Long memberId, String itemName, int itemPrice) {
    
            Member member = memberRepository.findById(memberId);
    
            int discountPrice = discountPolicy.discount(member, itemPrice);
    
            return new Order(memberId, itemName, itemPrice, discountPrice);
    
        }
    }

    受注および割引ポリシーの実行

    package hello.core;
    
    import hello.core.member.Grade;
    import hello.core.member.Member;
    import hello.core.member.MemberService;
    import hello.core.member.MemberServiceImpl;
    import hello.core.order.Order;
    import hello.core.order.OrderService;
    import hello.core.order.OrderServiceImpl;
    
    public class OrderApp {
    
        public static void main(String[] args) {
            MemberService memberService = new MemberServiceImpl();
            OrderService orderService = new OrderServiceImpl();
    
            Long memberId = 1L;
            Member member = new Member(1L, "memberA", Grade.VIP);
    
            memberService.join(member);
            Order order = orderService.createOrder(memberId, "itemA", 10000);
            System.out.println("order = " + order.toString());
    
    
        }
    }

    テストコード

    package hello.core.order;
    
    import hello.core.member.Grade;
    import hello.core.member.Member;
    import hello.core.member.MemberService;
    import hello.core.member.MemberServiceImpl;
    import org.assertj.core.api.Assertions;
    import org.junit.jupiter.api.Test;
    
    public class OrderServiceTest {
    
        MemberService memberService = new MemberServiceImpl();
        OrderService orderService = new OrderServiceImpl();
    
        @Test
        void createOrder() {
            Long memberId = 1L;
    
            Member member = new Member(memberId, "memberA", Grade.VIP);
    
            memberService.join(member);
    
            Order order = orderService.createOrder(memberId, "memberA", 10000);
    
            Assertions.assertThat(order.getDiscountPrice()).isEqualTo(1000);
        }
    }