@@ -0,0 +1,168 @@
+## 고민사항
+
+**고민** 
+~~~
+구현에 필요한 상품 목록과 행사 목록을 파일 입출력을 통해 불러온다.
+src/main/resources/products.md과 
+src/main/resources/promotions.md 파일을 이용한다.
+~~~
+* 마크다운 파일에 있는 내용을 어떻게 불러와 코드에 적용시킬 수 있을까?
+
+**해결 과정** 
+* BufferedReader 를 사용하여 파일 내용의 한 줄씩 입력받는 형식으로 한다.
+* 받아온 줄을 쉼표(,)로 구분하여 분리한다
+* 분리한 내용을 알맞게 원시값 포장 클래스에 할당한다.
+* 할당될 때, 빈 값이나 형식이 맞지 않으면 예외를 발생시킨다.
+* 또한, 테스트 해야 할 경우 파일 경로를 해당 객체 내부에 결정하면 다른 파일로 테스트 하지 못한다.
+* 따라서, 파일 경로를 주입받는 형식으로 작성하여 테스트를 진행할 수 있도록 한다.
+* 그리고 테스트 파일 설정 시, 마크다운에 빈 줄이 들어가지 않도록 주의한다. -> 빈 줄이 들어가면 버퍼리더가 공백을 읽어버린다.
+
+
+* 또한, 모든 파일의 내용을 저장한다. 프로그램 요구 사항에 따라, 파일 입출력을 통해 프로그램을 구현한다. -> 파일에 있는 내용은 enum으로 만들지 않을 것.
+
+----
+
+## 고민사항
+
+**고민**
+* 객체를 어떤식으로 나눠야 할까?
+
+**해결 과정**
+* 입력 형식이 ``[사이다-2],[감자칩-1]`` 이런식으로 들어옴. 즉, 중요한건 상품 이름과 수량
+* 가격은 그때 그때 더해주면 되기 때문에, 상품이름과 가격을 enum 으로 생성
+* 상품 객체를 만들고 이름과 수량을 필드로 가지도록 함
+* 그리고 프로모션의 경우는 Map 자료구조 형태를 사용해서 ``Map<상품, 프로모션>`` 형태로 나타냄
+* 이런 형식으로 하면 어떤 상품이 어떤 프로모션인지 잘 나타낼 수 있을 것 같음.
+* 나중에 프로모션 정보만 가지는 객체도 따로 만들어서 구입할 때, 비교하도록 하면 됨.
+
+
+
+* ``Map<상품, 프로모션>`` 자료구조를 사용할 필요가 없음을 알게 됌.
+* 상품 필드에 원시값 포장한 객체를 여러개 가져다 써도 된다는 것을 알았음.
+* 따라서, ``List<상품>`` 형식으로 필드를 구성
+----
+
+## 고민사항
+
+**고민**
+* 원시값 포장 객체에 있는 값을 반환하려 하니, ``Product.name().name()`` 형식을 통해 반환된다. 중복을 줄이고 싶음. 
+
+**해결 과정**
+* 객체를 받는 입장에서 어떤 방식으로 객체가 전달되는지 정확히 알아야 할까?
+* 해당된 값만 잘 받아서 구현되면 된다.
+* 따라서, ``Product.name()`` 만 했을 때, 값이 반환되도록 한다.
+
+----
+
+## 고민사항
+
+**고민**
+* 존재하지 않는 상품의 경우를 어떤식으로 처리할 수 있을까?
+
+**해결 과정**
+* 입력받은 품목들을 Products 클래스 특정 메서드에 매개변수로 던진다 
+* 이때, 어떻게 해당 항목이 들어있는지 검증할 수 있을까?
+* 상품명이 같은 경우 들어있다고 판단해야 한다.
+* 상품명이 같은 경우, 인스턴스 자체가 같다고 판단하면 로직이 더 간편해질 것 같다. 
+* 따라서, Product 클래스에 equals와 hashcode 메서드를 name에 관해서만 작성해야 한다.
+* ProductName 클래스에도 equals와 hashcode 메서드를 작성해야 한다.
+
+----
+
+## 고민사항
+
+**고민**
+* 구매 수량이 재고 수량을 초과한 경우를 어떤 식으로 처리할 수 있을까?
+
+**해결 과정**
+* 먼저, 해당 상품의 이름과 일치하는 모든 데이터를 가져온다.
+* 가져온 모든 상품의 재고를 합하여  비교한다.
+
+
+* 원래 있던 Products 클래스에 재고 검증 책임을 부여하니, 로직이 너무 많아지고 많은 책임을 지게 된다.
+* 따라서, 재고 검증하는 클래스를 따로 생성한다.
+
+---
+
+## 고민사항
+
+**고민**
+* 상품 입력 시, 기타 잘못된 경우를 어떻게 검증할 수 있을까?
+
+**해결 과정**
+* 기타 잘못된 경우를 검증하려면 [상품-개수] 해당 형식 자체가 아니어야 한다.
+* 따라서 정규식을 통해 검증한다.
+1. ```\\[``` : ```[```로 시작하는지 
+2. ```(.+)``` : 아무 문자가 하나 이상 있는지
+3. ``-`` : ``-``로 나뉘는지
+4. ```]``` : ``]`` 로 끝나는지
+
+
+* 최종 : ``\\[(.+)-(.+)]``
+
+-----
+
+## 고민사항
+
+**고민**
+* 상품의 프로모션 유무를 따져 어떻게 구매할까?
+
+**해결 과정**
+1. 해당 이름으로 프로모션 상품이 있는지 판별한다
+2. 프로모션 상품이 있을 경우
+   * 프로모션 개수가 구매한 개수보다 많은지 판별한다
+     * 프로모션 개수 >= 구매한 개수 : 프로모션 재고를 차감한다
+       * 프로모션 적용이 가능한 상품에 대해 고객이 해당 수량만큼 가져오지 않았을 경우, 혜택에 대한 안내 메시지를 출력한다.
+     * 프로모션 개수 < 구매한 개수 
+       * 프로모션이 얼마나 적용되는지 파악하고, 얼마나 적용 안되는지 파악한다
+       * 프로모션 재고에서 적용되는 만큼 차감하고, 적용 안되는 개수를 프로모션 재고와 일반 재고에서 차감한다.
+       ![프로모션 계산 이미지](/docs/image/프로모션계산.jpeg)
+       * 해당 이미지를 참고하여 계산 로직을 구현한다
+       * 프로모션 재고가 부족하여 일부 수량을 프로모션 혜택 없이 결제해야 하는 경우, 일부 수량에 대해 정가로 결제할지 여부에 대한 안내 메시지를 출력한다.
+
+     
+   
+
+----
+## 고민사항
+
+**고민**
+* 구매한 상품에서, 구매한 개수에 따른 프로모션 개수를 구해야 하지만, 현재 구매한 모든 상품은 promotion에 noPromotion을 할당함
+
+**해결 과정**
+* enum 을 선언하여 ``이름 - 어떤 프로모션인지 `` 형식으로 상수들을 정해줌
+* static 메서드로 이름에 따라 어떤 프로모션 값을 가져올지 정해줌
+* 이렇게 하면 구매한 상품을 생성할 때, Promotion 값도 지정해줄 수 있다.
+
+----
+## 고민사항
+
+**고민**
+* Promotion을 필드로 가지고 있는, Product 클래스에 프로모션 계산 로직을 작성하는 것이 맞을까?
+
+**해결 과정**
+* Product 클래스에 Promotion 계산 로직을 작성하니, 너무 많은 책임을 가지고 있는 것 같다.
+* 응집도 향상을 위해 Product 클래스에 상품 - 프로모션 관련 필드를 두었지만 계산 책임까지 가지는 것은 비효율적임.
+* 따라서 Promotion 관련 계산을 진행하는 PromotionService 클래스를 만든다.
+
+----
+
+## 고민사항
+
+**고민**
+* 영수증을 출력하기 위해, 영수증 객체에 어떤 정보를 담아야 할까?
+
+**해결 과정**
+* 영수증은 구매한 상품의 정보, 증정 수량, 총구매액, 행사할인, 멤버십, 내실 돈 정보가 있어야 한다.
+* 현재 프로모션에 관한 정보만 영수증에 등록할 것이기에 멥버십 관련 정보는 제외하고 진행한다.
+* Receipt 객체에 구매 상품 정보, 증정수량 정보만 가져와서 계산하면 된다.
+  * 행사 할인 정보의 경우, 해당 상품의 증정 수량을 파악해 계산하면 된다.
+  * 총 구매액의 경우, 해당 상품을 구매한 개수에 따라 계산하면 된다.
+  * 내실 돈 정보의 경우, 총 구매액에서 할인 들어간 가격을 빼면 된다.
+* 구매 상품 정보와 증정수량을 매칭해야 하기 때문에 List 형태 보다는, Map 자료구조 형태를 사용하는 것이 좋아보인다.
+
+
+* 영수증에 정보를 담았는데, 아직 멤버십을 합치지 않았음.
+* 멤버십을 합쳐서 정보를 보여주는 것은 CustomerReceipt 클래스를 파서 진행 (해당 클래스는 정보를 제공해주는 역할만 하도록)
+
+----

리뷰: README에 모두 작성하지 않고, 여러개로 분리하신 이유가 있을까요??