ewhk9887/korean_code_reviews_from_github huggingface dataset:
@@ -0,0 +1,90 @@
+package store.dto.request.file;
+
+import java.time.LocalDate;
+import java.util.List;
+import store.util.CommonParser;
+import store.util.CommonValidator;
+
+public class PromotionRequest {
+
+    private final String name;
+    private final Integer requiredCount;
+    private final Integer giftCount;
+    private final LocalDate startDate;
+    private final LocalDate endDate;
+
+    private PromotionRequest(String name, Integer requiredCount, Integer giftCount,
+                             LocalDate startDate, LocalDate endDate) {
+        this.name = name;
+        this.requiredCount = requiredCount;
+        this.giftCount = giftCount;
+        this.startDate = startDate;
+        this.endDate = endDate;
+    }
+
+    public static PromotionRequest from(String line) {
+        List<String> separatedLine = CommonParser.separateBySeparator(line, ",");
+
+        String name = parseName(separatedLine);
+        Integer requiredCount = parseRequiredCount(separatedLine);
+        Integer giftCount = parseGiftCount(separatedLine);
+        LocalDate startDate = parseStartDate(separatedLine);
+        LocalDate endDate = parseEndDate(separatedLine);
+
+        return new PromotionRequest(name, requiredCount, giftCount, startDate, endDate);
+    }
+
+    private static String parseName(List<String> line) {
+        String name = line.get(0);
+        CommonValidator.validateNotNull(name);
+        return name;
+    }
+
+    private static Integer parseRequiredCount(List<String> line) {
+        String purchaseRequiredCount = line.get(1);
+        CommonValidator.validateNotNull(purchaseRequiredCount);
+        CommonValidator.validateNumeric(purchaseRequiredCount);
+        return CommonParser.convertStringToInteger(purchaseRequiredCount);
+    }
+
+    private static Integer parseGiftCount(List<String> line) {
+        String giftCount = line.get(2);
+        CommonValidator.validateNotNull(giftCount);
+        CommonValidator.validateNumeric(giftCount);
+        return CommonParser.convertStringToInteger(giftCount);
+    }
+
+    private static LocalDate parseStartDate(List<String> line) {
+        String startDate = line.get(3);
+        CommonValidator.validateNotNull(startDate);
+        CommonValidator.validateDate(startDate);
+        return CommonParser.parseDate(startDate);
+    }
+
+    private static LocalDate parseEndDate(List<String> line) {
+        String endDate = line.get(4);
+        CommonValidator.validateNotNull(endDate);
+        CommonValidator.validateDate(endDate);
+        return CommonParser.parseDate(endDate);
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Integer getRequiredCount() {
+        return requiredCount;
+    }
+
+    public Integer getGiftCount() {
+        return giftCount;
+    }
+
+    public LocalDate getStartDate() {
+        return startDate;
+    }
+
+    public LocalDate getEndDate() {
+        return endDate;
+    }
+}

리뷰: ","은 상수화할 수 있을 것 같아요!
@@ -0,0 +1,90 @@
+package store.dto.request.file;
+
+import java.time.LocalDate;
+import java.util.List;
+import store.util.CommonParser;
+import store.util.CommonValidator;
+
+public class PromotionRequest {
+
+    private final String name;
+    private final Integer requiredCount;
+    private final Integer giftCount;
+    private final LocalDate startDate;
+    private final LocalDate endDate;
+
+    private PromotionRequest(String name, Integer requiredCount, Integer giftCount,
+                             LocalDate startDate, LocalDate endDate) {
+        this.name = name;
+        this.requiredCount = requiredCount;
+        this.giftCount = giftCount;
+        this.startDate = startDate;
+        this.endDate = endDate;
+    }
+
+    public static PromotionRequest from(String line) {
+        List<String> separatedLine = CommonParser.separateBySeparator(line, ",");
+
+        String name = parseName(separatedLine);
+        Integer requiredCount = parseRequiredCount(separatedLine);
+        Integer giftCount = parseGiftCount(separatedLine);
+        LocalDate startDate = parseStartDate(separatedLine);
+        LocalDate endDate = parseEndDate(separatedLine);
+
+        return new PromotionRequest(name, requiredCount, giftCount, startDate, endDate);
+    }
+
+    private static String parseName(List<String> line) {
+        String name = line.get(0);
+        CommonValidator.validateNotNull(name);
+        return name;
+    }
+
+    private static Integer parseRequiredCount(List<String> line) {
+        String purchaseRequiredCount = line.get(1);
+        CommonValidator.validateNotNull(purchaseRequiredCount);
+        CommonValidator.validateNumeric(purchaseRequiredCount);
+        return CommonParser.convertStringToInteger(purchaseRequiredCount);
+    }
+
+    private static Integer parseGiftCount(List<String> line) {
+        String giftCount = line.get(2);
+        CommonValidator.validateNotNull(giftCount);
+        CommonValidator.validateNumeric(giftCount);
+        return CommonParser.convertStringToInteger(giftCount);
+    }
+
+    private static LocalDate parseStartDate(List<String> line) {
+        String startDate = line.get(3);
+        CommonValidator.validateNotNull(startDate);
+        CommonValidator.validateDate(startDate);
+        return CommonParser.parseDate(startDate);
+    }
+
+    private static LocalDate parseEndDate(List<String> line) {
+        String endDate = line.get(4);
+        CommonValidator.validateNotNull(endDate);
+        CommonValidator.validateDate(endDate);
+        return CommonParser.parseDate(endDate);
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Integer getRequiredCount() {
+        return requiredCount;
+    }
+
+    public Integer getGiftCount() {
+        return giftCount;
+    }
+
+    public LocalDate getStartDate() {
+        return startDate;
+    }
+
+    public LocalDate getEndDate() {
+        return endDate;
+    }
+}

리뷰: 각 index가 어떤 필드를 의미하는지를 상수화하는 것도 좋을 것 같아요!
@@ -0,0 +1,90 @@
+package store.dto.request.file;
+
+import java.time.LocalDate;
+import java.util.List;
+import store.util.CommonParser;
+import store.util.CommonValidator;
+
+public class PromotionRequest {
+
+    private final String name;
+    private final Integer requiredCount;
+    private final Integer giftCount;
+    private final LocalDate startDate;
+    private final LocalDate endDate;
+
+    private PromotionRequest(String name, Integer requiredCount, Integer giftCount,
+                             LocalDate startDate, LocalDate endDate) {
+        this.name = name;
+        this.requiredCount = requiredCount;
+        this.giftCount = giftCount;
+        this.startDate = startDate;
+        this.endDate = endDate;
+    }
+
+    public static PromotionRequest from(String line) {
+        List<String> separatedLine = CommonParser.separateBySeparator(line, ",");
+
+        String name = parseName(separatedLine);
+        Integer requiredCount = parseRequiredCount(separatedLine);
+        Integer giftCount = parseGiftCount(separatedLine);
+        LocalDate startDate = parseStartDate(separatedLine);
+        LocalDate endDate = parseEndDate(separatedLine);
+
+        return new PromotionRequest(name, requiredCount, giftCount, startDate, endDate);
+    }
+
+    private static String parseName(List<String> line) {
+        String name = line.get(0);
+        CommonValidator.validateNotNull(name);
+        return name;
+    }
+
+    private static Integer parseRequiredCount(List<String> line) {
+        String purchaseRequiredCount = line.get(1);
+        CommonValidator.validateNotNull(purchaseRequiredCount);
+        CommonValidator.validateNumeric(purchaseRequiredCount);
+        return CommonParser.convertStringToInteger(purchaseRequiredCount);
+    }
+
+    private static Integer parseGiftCount(List<String> line) {
+        String giftCount = line.get(2);
+        CommonValidator.validateNotNull(giftCount);
+        CommonValidator.validateNumeric(giftCount);
+        return CommonParser.convertStringToInteger(giftCount);
+    }
+
+    private static LocalDate parseStartDate(List<String> line) {
+        String startDate = line.get(3);
+        CommonValidator.validateNotNull(startDate);
+        CommonValidator.validateDate(startDate);
+        return CommonParser.parseDate(startDate);
+    }
+
+    private static LocalDate parseEndDate(List<String> line) {
+        String endDate = line.get(4);
+        CommonValidator.validateNotNull(endDate);
+        CommonValidator.validateDate(endDate);
+        return CommonParser.parseDate(endDate);
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Integer getRequiredCount() {
+        return requiredCount;
+    }
+
+    public Integer getGiftCount() {
+        return giftCount;
+    }
+
+    public LocalDate getStartDate() {
+        return startDate;
+    }
+
+    public LocalDate getEndDate() {
+        return endDate;
+    }
+}

리뷰: DTO에 record를 활용하지 않은 이유가 있는지 궁금해요! 😄
@@ -0,0 +1,25 @@
+package store.dto.request.input;
+
+import store.util.CommonParser;
+import store.util.CommonValidator;
+
+public class AddingQuantityStatusRequest {
+
+    private final boolean addingQuantityStatus;
+
+    private AddingQuantityStatusRequest(boolean addingQuantityStatus) {
+        this.addingQuantityStatus = addingQuantityStatus;
+    }
+
+    public static AddingQuantityStatusRequest from(String input) {
+        CommonValidator.validateNotNull(input);
+        CommonValidator.validateYesOrNo(input);
+        boolean status = CommonParser.parseBoolean(input);
+
+        return new AddingQuantityStatusRequest(status);
+    }
+
+    public boolean isAddingQuantityStatus() {
+        return addingQuantityStatus;
+    }
+}

리뷰: 공통되는 검증 로직을 util 클래스로 분리해서 활용하는 부분이 인상깊네요!! 💯
@@ -0,0 +1,25 @@
+package store.dto.request.input;
+
+import store.util.CommonParser;
+import store.util.CommonValidator;
+
+public class AddingQuantityStatusRequest {
+
+    private final boolean addingQuantityStatus;
+
+    private AddingQuantityStatusRequest(boolean addingQuantityStatus) {
+        this.addingQuantityStatus = addingQuantityStatus;
+    }
+
+    public static AddingQuantityStatusRequest from(String input) {
+        CommonValidator.validateNotNull(input);
+        CommonValidator.validateYesOrNo(input);
+        boolean status = CommonParser.parseBoolean(input);
+
+        return new AddingQuantityStatusRequest(status);
+    }
+
+    public boolean isAddingQuantityStatus() {
+        return addingQuantityStatus;
+    }
+}

리뷰: addingQuantityStatus가 어떤 용도로 활용되는 것인지 알려주실 수 있을까요!?
@@ -0,0 +1,25 @@
+package store.dto.request.input;
+
+import store.util.CommonParser;
+import store.util.CommonValidator;
+
+public class AdditionalPurchaseStatusRequest {
+
+    private final boolean additionalPurchaseStatus;
+
+    private AdditionalPurchaseStatusRequest(boolean additionalPurchaseStatus) {
+        this.additionalPurchaseStatus = additionalPurchaseStatus;
+    }
+
+    public static AdditionalPurchaseStatusRequest from(String input) {
+        CommonValidator.validateNotNull(input);
+        CommonValidator.validateYesOrNo(input);
+        boolean status = CommonParser.parseBoolean(input);
+
+        return new AdditionalPurchaseStatusRequest(status);
+    }
+
+    public boolean isAdditionalPurchaseStatus() {
+        return additionalPurchaseStatus;
+    }
+}

리뷰: 정적 팩토리 메서드를 통해 검증 및 가공 로직을 캡슐화한 게 좋아보이네요! 👍
@@ -0,0 +1,70 @@
+package store.dto.request.input;
+
+import static store.constant.InputConstant.PRODUCT_SEPARATOR;
+
+import java.util.ArrayList;
+import java.util.List;
+import store.util.CommonParser;
+import store.util.CommonValidator;
+
+public class PurchaseProductsRequest {
+
+    private final List<InnerPurchaseProductRequest> purchaseProductsRequests;
+
+    private PurchaseProductsRequest(List<InnerPurchaseProductRequest> purchaseProductsRequests) {
+        this.purchaseProductsRequests = purchaseProductsRequests;
+    }
+
+    public static PurchaseProductsRequest from(String input) {
+        CommonValidator.validateNotNull(input);
+
+        List<InnerPurchaseProductRequest> newPurchaseProductRequests = new ArrayList<>();
+        List<String> separatedProducts = CommonParser.separateBySeparator(input, PRODUCT_SEPARATOR.getContent());
+        for (String separatedProduct : separatedProducts) {
+            String replacedProduct = CommonParser.replaceSquareBrackets(separatedProduct);
+            InnerPurchaseProductRequest newPurchaseProductRequest = InnerPurchaseProductRequest.from(replacedProduct);
+            newPurchaseProductRequests.add(newPurchaseProductRequest);
+        }
+        return new PurchaseProductsRequest(newPurchaseProductRequests);
+    }
+
+    public List<InnerPurchaseProductRequest> getPurchaseProductsRequests() {
+        return purchaseProductsRequests;
+    }
+
+    public static class InnerPurchaseProductRequest {
+
+        private final String productName;
+        private final Integer productQuantity;
+
+        private InnerPurchaseProductRequest(String productName, Integer productQuantity) {
+            this.productName = productName;
+            this.productQuantity = productQuantity;
+        }
+
+        private static InnerPurchaseProductRequest from(String separatedProduct) {
+            List<String> productEntry = CommonParser.separateBySeparator(separatedProduct, "-");
+            String productName = parseProductName(productEntry);
+            Integer productQuantity = parseProductQuantity(productEntry);
+            return new InnerPurchaseProductRequest(productName, productQuantity);
+        }
+
+        private static String parseProductName(List<String> productEntry) {
+            return productEntry.getFirst();
+        }
+
+        private static Integer parseProductQuantity(List<String> productEntry) {
+            String productQuantity = productEntry.getLast();
+            CommonValidator.validateNumeric(productQuantity);
+            return CommonParser.convertStringToInteger(productQuantity);
+        }
+
+        public String getProductName() {
+            return productName;
+        }
+
+        public Integer getProductQuantity() {
+            return productQuantity;
+        }
+    }
+}

리뷰: 메서드의 큰 틀에서 보면 newPurchaseProductRequests 리스트를 완성하는 것이 책임인 것 같은데 for문 내부 로직을 별도 메서드로 분리한다면`return separatedProducts.stream().` 형태로 리팩토링해볼 수 있을 것 같아요!
@@ -0,0 +1,70 @@
+package store.dto.request.input;
+
+import static store.constant.InputConstant.PRODUCT_SEPARATOR;
+
+import java.util.ArrayList;
+import java.util.List;
+import store.util.CommonParser;
+import store.util.CommonValidator;
+
+public class PurchaseProductsRequest {
+
+    private final List<InnerPurchaseProductRequest> purchaseProductsRequests;
+
+    private PurchaseProductsRequest(List<InnerPurchaseProductRequest> purchaseProductsRequests) {
+        this.purchaseProductsRequests = purchaseProductsRequests;
+    }
+
+    public static PurchaseProductsRequest from(String input) {
+        CommonValidator.validateNotNull(input);
+
+        List<InnerPurchaseProductRequest> newPurchaseProductRequests = new ArrayList<>();
+        List<String> separatedProducts = CommonParser.separateBySeparator(input, PRODUCT_SEPARATOR.getContent());
+        for (String separatedProduct : separatedProducts) {
+            String replacedProduct = CommonParser.replaceSquareBrackets(separatedProduct);
+            InnerPurchaseProductRequest newPurchaseProductRequest = InnerPurchaseProductRequest.from(replacedProduct);
+            newPurchaseProductRequests.add(newPurchaseProductRequest);
+        }
+        return new PurchaseProductsRequest(newPurchaseProductRequests);
+    }
+
+    public List<InnerPurchaseProductRequest> getPurchaseProductsRequests() {
+        return purchaseProductsRequests;
+    }
+
+    public static class InnerPurchaseProductRequest {
+
+        private final String productName;
+        private final Integer productQuantity;
+
+        private InnerPurchaseProductRequest(String productName, Integer productQuantity) {
+            this.productName = productName;
+            this.productQuantity = productQuantity;
+        }
+
+        private static InnerPurchaseProductRequest from(String separatedProduct) {
+            List<String> productEntry = CommonParser.separateBySeparator(separatedProduct, "-");
+            String productName = parseProductName(productEntry);
+            Integer productQuantity = parseProductQuantity(productEntry);
+            return new InnerPurchaseProductRequest(productName, productQuantity);
+        }
+
+        private static String parseProductName(List<String> productEntry) {
+            return productEntry.getFirst();
+        }
+
+        private static Integer parseProductQuantity(List<String> productEntry) {
+            String productQuantity = productEntry.getLast();
+            CommonValidator.validateNumeric(productQuantity);
+            return CommonParser.convertStringToInteger(productQuantity);
+        }
+
+        public String getProductName() {
+            return productName;
+        }
+
+        public Integer getProductQuantity() {
+            return productQuantity;
+        }
+    }
+}

리뷰: "-"는 상수화할 수 있을 것 같아요!
@@ -0,0 +1,70 @@
+package store.dto.request.input;
+
+import static store.constant.InputConstant.PRODUCT_SEPARATOR;
+
+import java.util.ArrayList;
+import java.util.List;
+import store.util.CommonParser;
+import store.util.CommonValidator;
+
+public class PurchaseProductsRequest {
+
+    private final List<InnerPurchaseProductRequest> purchaseProductsRequests;
+
+    private PurchaseProductsRequest(List<InnerPurchaseProductRequest> purchaseProductsRequests) {
+        this.purchaseProductsRequests = purchaseProductsRequests;
+    }
+
+    public static PurchaseProductsRequest from(String input) {
+        CommonValidator.validateNotNull(input);
+
+        List<InnerPurchaseProductRequest> newPurchaseProductRequests = new ArrayList<>();
+        List<String> separatedProducts = CommonParser.separateBySeparator(input, PRODUCT_SEPARATOR.getContent());
+        for (String separatedProduct : separatedProducts) {
+            String replacedProduct = CommonParser.replaceSquareBrackets(separatedProduct);
+            InnerPurchaseProductRequest newPurchaseProductRequest = InnerPurchaseProductRequest.from(replacedProduct);
+            newPurchaseProductRequests.add(newPurchaseProductRequest);
+        }
+        return new PurchaseProductsRequest(newPurchaseProductRequests);
+    }
+
+    public List<InnerPurchaseProductRequest> getPurchaseProductsRequests() {
+        return purchaseProductsRequests;
+    }
+
+    public static class InnerPurchaseProductRequest {
+
+        private final String productName;
+        private final Integer productQuantity;
+
+        private InnerPurchaseProductRequest(String productName, Integer productQuantity) {
+            this.productName = productName;
+            this.productQuantity = productQuantity;
+        }
+
+        private static InnerPurchaseProductRequest from(String separatedProduct) {
+            List<String> productEntry = CommonParser.separateBySeparator(separatedProduct, "-");
+            String productName = parseProductName(productEntry);
+            Integer productQuantity = parseProductQuantity(productEntry);
+            return new InnerPurchaseProductRequest(productName, productQuantity);
+        }
+
+        private static String parseProductName(List<String> productEntry) {
+            return productEntry.getFirst();
+        }
+
+        private static Integer parseProductQuantity(List<String> productEntry) {
+            String productQuantity = productEntry.getLast();
+            CommonValidator.validateNumeric(productQuantity);
+            return CommonParser.convertStringToInteger(productQuantity);
+        }
+
+        public String getProductName() {
+            return productName;
+        }
+
+        public Integer getProductQuantity() {
+            return productQuantity;
+        }
+    }
+}

리뷰: 내부 클래스를 static으로 정의하신 이유가 무엇인가요!?
@@ -0,0 +1,70 @@
+package store.dto.request.input;
+
+import static store.constant.InputConstant.PRODUCT_SEPARATOR;
+
+import java.util.ArrayList;
+import java.util.List;
+import store.util.CommonParser;
+import store.util.CommonValidator;
+
+public class PurchaseProductsRequest {
+
+    private final List<InnerPurchaseProductRequest> purchaseProductsRequests;
+
+    private PurchaseProductsRequest(List<InnerPurchaseProductRequest> purchaseProductsRequests) {
+        this.purchaseProductsRequests = purchaseProductsRequests;
+    }
+
+    public static PurchaseProductsRequest from(String input) {
+        CommonValidator.validateNotNull(input);
+
+        List<InnerPurchaseProductRequest> newPurchaseProductRequests = new ArrayList<>();
+        List<String> separatedProducts = CommonParser.separateBySeparator(input, PRODUCT_SEPARATOR.getContent());
+        for (String separatedProduct : separatedProducts) {
+            String replacedProduct = CommonParser.replaceSquareBrackets(separatedProduct);
+            InnerPurchaseProductRequest newPurchaseProductRequest = InnerPurchaseProductRequest.from(replacedProduct);
+            newPurchaseProductRequests.add(newPurchaseProductRequest);
+        }
+        return new PurchaseProductsRequest(newPurchaseProductRequests);
+    }
+
+    public List<InnerPurchaseProductRequest> getPurchaseProductsRequests() {
+        return purchaseProductsRequests;
+    }
+
+    public static class InnerPurchaseProductRequest {
+
+        private final String productName;
+        private final Integer productQuantity;
+
+        private InnerPurchaseProductRequest(String productName, Integer productQuantity) {
+            this.productName = productName;
+            this.productQuantity = productQuantity;
+        }
+
+        private static InnerPurchaseProductRequest from(String separatedProduct) {
+            List<String> productEntry = CommonParser.separateBySeparator(separatedProduct, "-");
+            String productName = parseProductName(productEntry);
+            Integer productQuantity = parseProductQuantity(productEntry);
+            return new InnerPurchaseProductRequest(productName, productQuantity);
+        }
+
+        private static String parseProductName(List<String> productEntry) {
+            return productEntry.getFirst();
+        }
+
+        private static Integer parseProductQuantity(List<String> productEntry) {
+            String productQuantity = productEntry.getLast();
+            CommonValidator.validateNumeric(productQuantity);
+            return CommonParser.convertStringToInteger(productQuantity);
+        }
+
+        public String getProductName() {
+            return productName;
+        }
+
+        public Integer getProductQuantity() {
+            return productQuantity;
+        }
+    }
+}

리뷰: Integer는 null값이 담길 수 있는데 int로 유지하는 것은 어떻게 생각하시나요!?