From 8f9fd3a2f5f9362c3e5e488c2bab1d4dd8afa058 Mon Sep 17 00:00:00 2001 From: Yiseull Date: Sun, 2 Jul 2023 14:07:49 +0900 Subject: [PATCH 01/28] =?UTF-8?q?test:=20MemoryVoucherRepository=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MemoryVoucherRepositoryTest.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/test/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepositoryTest.java diff --git a/src/test/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepositoryTest.java b/src/test/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepositoryTest.java new file mode 100644 index 0000000000..242148dbb2 --- /dev/null +++ b/src/test/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepositoryTest.java @@ -0,0 +1,46 @@ +package com.programmers.vouchermanagement.voucher.infrastructure; + +import com.programmers.vouchermanagement.voucher.domain.FixedAmountVoucher; +import com.programmers.vouchermanagement.voucher.domain.PercentDiscountVoucher; +import com.programmers.vouchermanagement.voucher.domain.Voucher; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class MemoryVoucherRepositoryTest { + + MemoryVoucherRepository memoryVoucherRepository = new MemoryVoucherRepository(); + + @Test + @DisplayName("바우처를 저장한다.") + void save() { + // given + FixedAmountVoucher voucher = new FixedAmountVoucher(100); + + // when + Voucher result = memoryVoucherRepository.save(voucher); + + // then + assertThat(result.getId()).isEqualTo(voucher.getId()); + } + + @Test + @DisplayName("바우처를 모두 조회한다.") + void findAll() { + // given + FixedAmountVoucher voucher1 = new FixedAmountVoucher(100); + PercentDiscountVoucher voucher2 = new PercentDiscountVoucher(30); + + memoryVoucherRepository.save(voucher1); + memoryVoucherRepository.save(voucher2); + + // when + List result = memoryVoucherRepository.findAll(); + + // then + assertThat(result).hasSize(2); + } +} \ No newline at end of file From 32005470db422f582c5c2208056be677f90cde94 Mon Sep 17 00:00:00 2001 From: Yiseull Date: Sun, 2 Jul 2023 19:24:42 +0900 Subject: [PATCH 02/28] =?UTF-8?q?test:=20DiscountType=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../voucher/domain/DiscountTypeTest.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/test/java/com/programmers/vouchermanagement/voucher/domain/DiscountTypeTest.java diff --git a/src/test/java/com/programmers/vouchermanagement/voucher/domain/DiscountTypeTest.java b/src/test/java/com/programmers/vouchermanagement/voucher/domain/DiscountTypeTest.java new file mode 100644 index 0000000000..eed5af001a --- /dev/null +++ b/src/test/java/com/programmers/vouchermanagement/voucher/domain/DiscountTypeTest.java @@ -0,0 +1,56 @@ +package com.programmers.vouchermanagement.voucher.domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class DiscountTypeTest { + + @Nested + @DisplayName("할인 유형에 적합한 DiscountType 을 반환한다.") + class returnAppropriateDiscountType { + + @Test + @DisplayName("fix 가 들어온 경우") + void WhenFixComeInto() { + // when + String name = "fix"; + + // given + DiscountType result = DiscountType.from(name); + + // then + assertThat(result).isEqualTo(DiscountType.FIX); + } + + @Test + @DisplayName("percent 가 들어온 경우") + void WhenPercentComeInto() { + // when + String name = "percent"; + + // given + DiscountType result = DiscountType.from(name); + + // then + assertThat(result).isEqualTo(DiscountType.PERCENT); + } + } + + @Test + @DisplayName("존재하지 않는 할인 유형이 들어오면 에외가 발생한다.") + void occurExceptionWhenDiscountTypeDoesNotExist() { + // when + String name = "fixx"; + + // given & then + assertThatThrownBy(() -> { + DiscountType.from(name); + }) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("This discount type does not exist."); + } +} \ No newline at end of file From 4ed44ef6ef4e913858c29f14a7c6a30e5c609ec2 Mon Sep 17 00:00:00 2001 From: Yiseull Date: Sun, 2 Jul 2023 19:30:11 +0900 Subject: [PATCH 03/28] =?UTF-8?q?test:=20=ED=95=A0=EC=9D=B8=20=EC=9C=A0?= =?UTF-8?q?=ED=98=95=EC=97=90=20=EB=A7=9E=EB=8A=94=20=EB=B0=94=EC=9A=B0?= =?UTF-8?q?=EC=B2=98=20=EC=83=9D=EC=84=B1=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/VoucherFactoryTest.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherFactoryTest.java diff --git a/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherFactoryTest.java b/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherFactoryTest.java new file mode 100644 index 0000000000..783a675c7e --- /dev/null +++ b/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherFactoryTest.java @@ -0,0 +1,41 @@ +package com.programmers.vouchermanagement.voucher.application; + +import com.programmers.vouchermanagement.voucher.domain.DiscountType; +import com.programmers.vouchermanagement.voucher.domain.FixedAmountVoucher; +import com.programmers.vouchermanagement.voucher.domain.PercentDiscountVoucher; +import com.programmers.vouchermanagement.voucher.domain.Voucher; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class VoucherFactoryTest { + + @Test + @DisplayName("정액 할인 바우처를 생성한다.") + void createFixedAmountVoucher() { + // given + DiscountType discountType = DiscountType.FIX; + int discountAmount = 10; + + // when + Voucher result = VoucherFactory.createVoucher(discountType, discountAmount); + + // then + assertThat(result).isInstanceOf(FixedAmountVoucher.class); + } + + @Test + @DisplayName("정률 할인 바우처를 생성한다.") + void createPercentDiscountVoucher() { + // given + DiscountType discountType = DiscountType.PERCENT; + int discountAmount = 10; + + // when + Voucher result = VoucherFactory.createVoucher(discountType, discountAmount); + + // then + assertThat(result).isInstanceOf(PercentDiscountVoucher.class); + } +} \ No newline at end of file From d200810b89560495ed6ea4852523292d8d8e4c8b Mon Sep 17 00:00:00 2001 From: Yiseull Date: Sun, 2 Jul 2023 20:17:50 +0900 Subject: [PATCH 04/28] =?UTF-8?q?test:=20=EC=A0=95=EC=95=A1=20=ED=95=A0?= =?UTF-8?q?=EC=9D=B8=20=EB=B0=94=EC=9A=B0=EC=B2=98=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../voucher/domain/FixedAmountVoucher.java | 2 +- .../domain/FixedAmountVoucherTest.java | 52 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountVoucherTest.java diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountVoucher.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountVoucher.java index 4d5fdb52fa..c2dc999a45 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountVoucher.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountVoucher.java @@ -16,7 +16,7 @@ public FixedAmountVoucher(int amount) { } private void validationAmount(int amount) { - if (amount <= MIN_AMOUNT) { + if (amount < MIN_AMOUNT) { throw new IllegalArgumentException("The minimum discount amount is 1."); } } diff --git a/src/test/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountVoucherTest.java b/src/test/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountVoucherTest.java new file mode 100644 index 0000000000..199621ecfb --- /dev/null +++ b/src/test/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountVoucherTest.java @@ -0,0 +1,52 @@ +package com.programmers.vouchermanagement.voucher.domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.assertj.core.api.Assertions.*; + +class FixedAmountVoucherTest { + + @Nested + @DisplayName("할인 금액을 검증한다.") + class validationAmount { + + @ParameterizedTest + @ValueSource(ints = {1, 10}) + @DisplayName("최소 할인 금액 이상인 경우 예외가 발생하지 않는다.") + void isMoreThanMinAmount(int amount) { + // when & then + assertThatCode(() -> new FixedAmountVoucher(amount)) + .doesNotThrowAnyException(); + } + + @ParameterizedTest + @ValueSource(ints = {0, -1}) + @DisplayName("최소 할인 금액 미만인 경우 예외가 발생한다.") + void lessThanMinAmount(int amount) { + // when & then + assertThatThrownBy(() -> { + new FixedAmountVoucher(amount); + }) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("The minimum discount amount is 1."); + } + } + + @ParameterizedTest + @CsvSource({"20000, 10000", "10000, 0", "5000, 0"}) + @DisplayName("정액 할인을 적용한다.") + void discount(int originalPrice, int expected) { + // given + FixedAmountVoucher fixedAmountVoucher = new FixedAmountVoucher(10000); + + // when + int result = fixedAmountVoucher.discount(originalPrice); + + // then + assertThat(result).isEqualTo(expected); + } +} \ No newline at end of file From 7c8a752293d912342f86f38effbb8a7a228c9af7 Mon Sep 17 00:00:00 2001 From: Yiseull Date: Sun, 2 Jul 2023 21:20:09 +0900 Subject: [PATCH 05/28] =?UTF-8?q?test:=20=EC=A0=95=EB=A5=A0=20=ED=95=A0?= =?UTF-8?q?=EC=9D=B8=20=EB=B0=94=EC=9A=B0=EC=B2=98=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/PercentDiscountVoucher.java | 10 +++- .../domain/PercentDiscountVoucherTest.java | 52 +++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountVoucherTest.java diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountVoucher.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountVoucher.java index 8c348dc9ca..a6fb0fe8e3 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountVoucher.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountVoucher.java @@ -1,5 +1,6 @@ package com.programmers.vouchermanagement.voucher.domain; +import java.math.BigDecimal; import java.util.UUID; public class PercentDiscountVoucher implements Voucher { @@ -29,6 +30,13 @@ public UUID getId() { @Override public int discount(int originalPrice) { - return originalPrice * (amount / MAX_PERCENT); + int discountedAmount = calculateDiscountedAmount(originalPrice); + return originalPrice - discountedAmount; + } + + private int calculateDiscountedAmount(int originalPrice) { + BigDecimal percent = BigDecimal.valueOf(amount).divide(BigDecimal.valueOf(MAX_PERCENT)); + BigDecimal discountedAmount = percent.multiply(BigDecimal.valueOf(originalPrice)); + return discountedAmount.intValue(); } } diff --git a/src/test/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountVoucherTest.java b/src/test/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountVoucherTest.java new file mode 100644 index 0000000000..3270283d76 --- /dev/null +++ b/src/test/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountVoucherTest.java @@ -0,0 +1,52 @@ +package com.programmers.vouchermanagement.voucher.domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.assertj.core.api.Assertions.*; + +class PercentDiscountVoucherTest { + + @Nested + @DisplayName("할인률을 검증한다.") + class validationAmount { + + @ParameterizedTest + @ValueSource(ints = {1, 50, 100}) + @DisplayName("할인률이 1에서 100 사이인 경우 예외가 발생하지 않는다.") + void isBetween1And100(int amount) { + // when & then + assertThatCode(() -> new PercentDiscountVoucher(amount)) + .doesNotThrowAnyException(); + } + + @ParameterizedTest + @ValueSource(ints = {-1, 0, 101}) + @DisplayName("할인률이 1에서 100 사이가 아닌 경우 예외가 발생한다.") + void isNotBetween1And100(int amount) { + // when & then + assertThatThrownBy(() -> { + new PercentDiscountVoucher(amount); + }) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("The discount percentage must be between 1 and 100%."); + } + } + + @ParameterizedTest + @CsvSource({"10, 9000", "50, 5000", "100, 0", "33, 6700"}) + @DisplayName("정률 할인을 적용한다.") + void discount(int amount, int expected) { + // given + PercentDiscountVoucher percentDiscountVoucher = new PercentDiscountVoucher(amount); + + // when + int result = percentDiscountVoucher.discount(10000); + + // then + assertThat(result).isEqualTo(expected); + } +} \ No newline at end of file From bcd3ab0426b238f953676d886ad4b23623618844 Mon Sep 17 00:00:00 2001 From: Yiseull Date: Sun, 2 Jul 2023 23:43:05 +0900 Subject: [PATCH 06/28] =?UTF-8?q?test:=20VoucherService=20=EB=B0=94?= =?UTF-8?q?=EC=9A=B0=EC=B2=98=20=EC=A1=B0=ED=9A=8C=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/VoucherServiceTest.java | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherServiceTest.java diff --git a/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherServiceTest.java b/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherServiceTest.java new file mode 100644 index 0000000000..8c75015278 --- /dev/null +++ b/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherServiceTest.java @@ -0,0 +1,50 @@ +package com.programmers.vouchermanagement.voucher.application; + +import com.programmers.vouchermanagement.voucher.domain.FixedAmountVoucher; +import com.programmers.vouchermanagement.voucher.domain.PercentDiscountVoucher; +import com.programmers.vouchermanagement.voucher.domain.Voucher; +import com.programmers.vouchermanagement.voucher.domain.VoucherRepository; +import com.programmers.vouchermanagement.voucher.dto.VoucherDto; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +@ExtendWith(MockitoExtension.class) +class VoucherServiceTest { + + @InjectMocks + private VoucherService voucherService; + + @Mock + private VoucherRepository voucherRepository; + + @Test + @DisplayName("바우처를 모두 조회한다.") + void getVouchers() { + // given + Voucher voucher1 = new FixedAmountVoucher(5000); + Voucher voucher2 = new PercentDiscountVoucher(10); + + given(voucherRepository.findAll()) + .willReturn(List.of(voucher1, voucher2)); + + // when + VoucherDto.Response result = voucherService.getVouchers(); + + // then + assertThat(result.voucherName()).hasSize(2); + + // verify + verify(voucherRepository, times(1)).findAll(); + } +} \ No newline at end of file From 663b097a100ed4b89cd47981a81e0fb1866587b1 Mon Sep 17 00:00:00 2001 From: Yiseull Date: Tue, 4 Jul 2023 00:09:38 +0900 Subject: [PATCH 07/28] =?UTF-8?q?test:=20VoucherService=20=EB=B0=94?= =?UTF-8?q?=EC=9A=B0=EC=B2=98=20=EC=83=9D=EC=84=B1=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../voucher/application/VoucherService.java | 4 +-- .../application/VoucherServiceTest.java | 26 ++++++++++++++++--- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherService.java b/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherService.java index f27d10b8c0..5ad6852649 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherService.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherService.java @@ -16,10 +16,10 @@ public class VoucherService { private final VoucherRepository voucherRepository; - public void createVoucher(VoucherDto.Request request) { + public Voucher createVoucher(VoucherDto.Request request) { Voucher voucher = VoucherFactory.createVoucher(request.discountType(), request.discountAmount()); - voucherRepository.save(voucher); log.info("Create Voucher! DiscountType: {}, DiscountAmount: {}", voucher.getClass().getSimpleName(), request.discountAmount()); + return voucherRepository.save(voucher); } public VoucherDto.Response getVouchers() { diff --git a/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherServiceTest.java b/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherServiceTest.java index 8c75015278..3fcb6b88d6 100644 --- a/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherServiceTest.java +++ b/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherServiceTest.java @@ -1,9 +1,6 @@ package com.programmers.vouchermanagement.voucher.application; -import com.programmers.vouchermanagement.voucher.domain.FixedAmountVoucher; -import com.programmers.vouchermanagement.voucher.domain.PercentDiscountVoucher; -import com.programmers.vouchermanagement.voucher.domain.Voucher; -import com.programmers.vouchermanagement.voucher.domain.VoucherRepository; +import com.programmers.vouchermanagement.voucher.domain.*; import com.programmers.vouchermanagement.voucher.dto.VoucherDto; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -15,6 +12,7 @@ import java.util.List; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -28,6 +26,26 @@ class VoucherServiceTest { @Mock private VoucherRepository voucherRepository; + @Test + @DisplayName("바우처를 생성한다.") + void createVoucher() { + // given + VoucherDto.Request request = new VoucherDto.Request(DiscountType.FIX, 5000); + Voucher voucher = VoucherFactory.createVoucher(request.discountType(), request.discountAmount()); + + given(voucherRepository.save(any(Voucher.class))) + .willReturn(voucher); + + // when + Voucher result = voucherService.createVoucher(request); + + // then + assertThat(result).isNotNull(); + + // verify + verify(voucherRepository, times(1)).save(any(Voucher.class)); + } + @Test @DisplayName("바우처를 모두 조회한다.") void getVouchers() { From 2dbdf9df02352a1d1a8bc10366237f0e657a13b1 Mon Sep 17 00:00:00 2001 From: Yiseull Date: Tue, 4 Jul 2023 14:36:56 +0900 Subject: [PATCH 08/28] =?UTF-8?q?chore:=20JDBC,=20MySQL,=20H2=20=EC=9D=98?= =?UTF-8?q?=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/build.gradle b/build.gradle index 997b13c0fb..dc5654fb65 100644 --- a/build.gradle +++ b/build.gradle @@ -16,6 +16,15 @@ repositories { } dependencies { + // JDBC + implementation 'org.springframework.boot:spring-boot-starter-jdbc' + + // MySQL + runtimeOnly 'com.mysql:mysql-connector-j:8.0.33' + + // H2 + runtimeOnly 'com.h2database:h2' + // Lombok compileOnly 'org.projectlombok:lombok:1.18.26' annotationProcessor 'org.projectlombok:lombok:1.18.26' From bf9f00422363d9381500c170b47977f2218ed0ca Mon Sep 17 00:00:00 2001 From: Yiseull Date: Tue, 4 Jul 2023 23:55:30 +0900 Subject: [PATCH 09/28] =?UTF-8?q?refactor:=20=EB=B0=94=EC=9A=B0=EC=B2=98?= =?UTF-8?q?=20=EB=8F=84=EB=A9=94=EC=9D=B8=20=EC=9E=AC=EC=84=A4=EA=B3=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../voucher/application/VoucherFactory.java | 16 -------- .../voucher/application/VoucherService.java | 5 ++- .../voucher/domain/DiscountPolicy.java | 6 +++ .../voucher/domain/DiscountType.java | 12 ++++-- ...er.java => FixedAmountDiscountPolicy.java} | 13 +----- ...oucher.java => PercentDiscountPolicy.java} | 12 +----- .../voucher/domain/Voucher.java | 22 ++++++++-- .../application/VoucherFactoryTest.java | 41 ------------------- .../application/VoucherServiceTest.java | 8 ++-- ...ava => FixedAmountDiscountPolicyTest.java} | 12 +++--- ...st.java => PercentDiscountPolicyTest.java} | 12 +++--- .../MemoryVoucherRepositoryTest.java | 13 +++--- 12 files changed, 64 insertions(+), 108 deletions(-) delete mode 100644 src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherFactory.java create mode 100644 src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountPolicy.java rename src/main/java/com/programmers/vouchermanagement/voucher/domain/{FixedAmountVoucher.java => FixedAmountDiscountPolicy.java} (68%) rename src/main/java/com/programmers/vouchermanagement/voucher/domain/{PercentDiscountVoucher.java => PercentDiscountPolicy.java} (79%) delete mode 100644 src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherFactoryTest.java rename src/test/java/com/programmers/vouchermanagement/voucher/domain/{FixedAmountVoucherTest.java => FixedAmountDiscountPolicyTest.java} (80%) rename src/test/java/com/programmers/vouchermanagement/voucher/domain/{PercentDiscountVoucherTest.java => PercentDiscountPolicyTest.java} (79%) diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherFactory.java b/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherFactory.java deleted file mode 100644 index f83bc1ac02..0000000000 --- a/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherFactory.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.programmers.vouchermanagement.voucher.application; - -import com.programmers.vouchermanagement.voucher.domain.DiscountType; -import com.programmers.vouchermanagement.voucher.domain.FixedAmountVoucher; -import com.programmers.vouchermanagement.voucher.domain.PercentDiscountVoucher; -import com.programmers.vouchermanagement.voucher.domain.Voucher; - -public class VoucherFactory { - - public static Voucher createVoucher(DiscountType discountType, int discountAmount) { - if (discountType == DiscountType.FIX) { - return new FixedAmountVoucher(discountAmount); - } - return new PercentDiscountVoucher(discountAmount); - } -} diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherService.java b/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherService.java index 5ad6852649..0415e5ccf7 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherService.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherService.java @@ -1,5 +1,6 @@ package com.programmers.vouchermanagement.voucher.application; +import com.programmers.vouchermanagement.voucher.domain.DiscountType; import com.programmers.vouchermanagement.voucher.domain.Voucher; import com.programmers.vouchermanagement.voucher.domain.VoucherRepository; import com.programmers.vouchermanagement.voucher.dto.VoucherDto; @@ -17,7 +18,9 @@ public class VoucherService { private final VoucherRepository voucherRepository; public Voucher createVoucher(VoucherDto.Request request) { - Voucher voucher = VoucherFactory.createVoucher(request.discountType(), request.discountAmount()); + DiscountType discountType = request.discountType(); + int amount = request.discountAmount(); + Voucher voucher = discountType.createVoucher(amount); log.info("Create Voucher! DiscountType: {}, DiscountAmount: {}", voucher.getClass().getSimpleName(), request.discountAmount()); return voucherRepository.save(voucher); } diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountPolicy.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountPolicy.java new file mode 100644 index 0000000000..736517bc54 --- /dev/null +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountPolicy.java @@ -0,0 +1,6 @@ +package com.programmers.vouchermanagement.voucher.domain; + +public abstract class DiscountPolicy { + + abstract int discount(int originalPrice); +} diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountType.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountType.java index 43a7ed1426..f8fd42fb6e 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountType.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountType.java @@ -8,10 +8,11 @@ public enum DiscountType { - FIX("fix"), - PERCENT("percent"); + FIX("fix", (amount) -> new Voucher(new FixedAmountDiscountPolicy(amount))), + PERCENT("percent", (amount) -> new Voucher(new PercentDiscountPolicy(amount))); private final String name; + private final Function function; private static final Map DISCOUNT_TYPE_MAP; static { @@ -19,8 +20,9 @@ public enum DiscountType { .collect(Collectors.toMap(DiscountType::getName, Function.identity()))); } - DiscountType(String name) { + DiscountType(String name, Function function) { this.name = name; + this.function = function; } public String getName() { @@ -33,4 +35,8 @@ public static DiscountType from(String name) { } throw new IllegalArgumentException("This discount type does not exist."); } + + public Voucher createVoucher(int amount) { + return function.apply(amount); + } } diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountVoucher.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicy.java similarity index 68% rename from src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountVoucher.java rename to src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicy.java index c2dc999a45..07b408b1e1 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountVoucher.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicy.java @@ -1,17 +1,13 @@ package com.programmers.vouchermanagement.voucher.domain; -import java.util.UUID; - -public class FixedAmountVoucher implements Voucher { +public class FixedAmountDiscountPolicy extends DiscountPolicy { public static final int MIN_AMOUNT = 1; - private final UUID id; private final int amount; - public FixedAmountVoucher(int amount) { + public FixedAmountDiscountPolicy(int amount) { validationAmount(amount); - this.id = UUID.randomUUID(); this.amount = amount; } @@ -21,11 +17,6 @@ private void validationAmount(int amount) { } } - @Override - public UUID getId() { - return this.id; - } - @Override public int discount(int originalPrice) { if (amount > originalPrice) { diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountVoucher.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicy.java similarity index 79% rename from src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountVoucher.java rename to src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicy.java index a6fb0fe8e3..ccdcee7690 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountVoucher.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicy.java @@ -1,19 +1,16 @@ package com.programmers.vouchermanagement.voucher.domain; import java.math.BigDecimal; -import java.util.UUID; -public class PercentDiscountVoucher implements Voucher { +public class PercentDiscountPolicy extends DiscountPolicy { public static final int MIN_PERCENT = 1; public static final int MAX_PERCENT = 100; - private final UUID id; private final int amount; - public PercentDiscountVoucher(int amount) { + public PercentDiscountPolicy(int amount) { validationAmount(amount); - this.id = UUID.randomUUID(); this.amount = amount; } @@ -23,11 +20,6 @@ private void validationAmount(int amount) { } } - @Override - public UUID getId() { - return this.id; - } - @Override public int discount(int originalPrice) { int discountedAmount = calculateDiscountedAmount(originalPrice); diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/Voucher.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/Voucher.java index fd955ae5b4..b70f183f82 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/Voucher.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/Voucher.java @@ -2,9 +2,25 @@ import java.util.UUID; -public interface Voucher { +public class Voucher { - UUID getId(); + private final UUID id; + private final DiscountPolicy discountPolicy; - int discount(int originalPrice); + public Voucher(DiscountPolicy discountPolicy) { + this.id = UUID.randomUUID(); + this.discountPolicy = discountPolicy; + } + + public UUID getId() { + return id; + } + + public DiscountPolicy getDiscountPolicy() { + return discountPolicy; + } + + public int discount(int originalPrice) { + return discountPolicy.discount(originalPrice); + } } diff --git a/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherFactoryTest.java b/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherFactoryTest.java deleted file mode 100644 index 783a675c7e..0000000000 --- a/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherFactoryTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.programmers.vouchermanagement.voucher.application; - -import com.programmers.vouchermanagement.voucher.domain.DiscountType; -import com.programmers.vouchermanagement.voucher.domain.FixedAmountVoucher; -import com.programmers.vouchermanagement.voucher.domain.PercentDiscountVoucher; -import com.programmers.vouchermanagement.voucher.domain.Voucher; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -class VoucherFactoryTest { - - @Test - @DisplayName("정액 할인 바우처를 생성한다.") - void createFixedAmountVoucher() { - // given - DiscountType discountType = DiscountType.FIX; - int discountAmount = 10; - - // when - Voucher result = VoucherFactory.createVoucher(discountType, discountAmount); - - // then - assertThat(result).isInstanceOf(FixedAmountVoucher.class); - } - - @Test - @DisplayName("정률 할인 바우처를 생성한다.") - void createPercentDiscountVoucher() { - // given - DiscountType discountType = DiscountType.PERCENT; - int discountAmount = 10; - - // when - Voucher result = VoucherFactory.createVoucher(discountType, discountAmount); - - // then - assertThat(result).isInstanceOf(PercentDiscountVoucher.class); - } -} \ No newline at end of file diff --git a/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherServiceTest.java b/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherServiceTest.java index 3fcb6b88d6..3eda61b647 100644 --- a/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherServiceTest.java +++ b/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherServiceTest.java @@ -31,7 +31,9 @@ class VoucherServiceTest { void createVoucher() { // given VoucherDto.Request request = new VoucherDto.Request(DiscountType.FIX, 5000); - Voucher voucher = VoucherFactory.createVoucher(request.discountType(), request.discountAmount()); + DiscountType discountType = request.discountType(); + int amount = request.discountAmount(); + Voucher voucher = discountType.createVoucher(amount); given(voucherRepository.save(any(Voucher.class))) .willReturn(voucher); @@ -50,8 +52,8 @@ void createVoucher() { @DisplayName("바우처를 모두 조회한다.") void getVouchers() { // given - Voucher voucher1 = new FixedAmountVoucher(5000); - Voucher voucher2 = new PercentDiscountVoucher(10); + Voucher voucher1 = new Voucher(new FixedAmountDiscountPolicy(5000)); + Voucher voucher2 = new Voucher(new PercentDiscountPolicy(10)); given(voucherRepository.findAll()) .willReturn(List.of(voucher1, voucher2)); diff --git a/src/test/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountVoucherTest.java b/src/test/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicyTest.java similarity index 80% rename from src/test/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountVoucherTest.java rename to src/test/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicyTest.java index 199621ecfb..5af17f7ae9 100644 --- a/src/test/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountVoucherTest.java +++ b/src/test/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicyTest.java @@ -8,7 +8,7 @@ import static org.assertj.core.api.Assertions.*; -class FixedAmountVoucherTest { +class FixedAmountDiscountPolicyTest { @Nested @DisplayName("할인 금액을 검증한다.") @@ -19,7 +19,7 @@ class validationAmount { @DisplayName("최소 할인 금액 이상인 경우 예외가 발생하지 않는다.") void isMoreThanMinAmount(int amount) { // when & then - assertThatCode(() -> new FixedAmountVoucher(amount)) + assertThatCode(() -> new FixedAmountDiscountPolicy(amount)) .doesNotThrowAnyException(); } @@ -28,9 +28,7 @@ void isMoreThanMinAmount(int amount) { @DisplayName("최소 할인 금액 미만인 경우 예외가 발생한다.") void lessThanMinAmount(int amount) { // when & then - assertThatThrownBy(() -> { - new FixedAmountVoucher(amount); - }) + assertThatThrownBy(() -> new FixedAmountDiscountPolicy(amount)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("The minimum discount amount is 1."); } @@ -41,10 +39,10 @@ void lessThanMinAmount(int amount) { @DisplayName("정액 할인을 적용한다.") void discount(int originalPrice, int expected) { // given - FixedAmountVoucher fixedAmountVoucher = new FixedAmountVoucher(10000); + DiscountPolicy discountPolicy = new FixedAmountDiscountPolicy(10000); // when - int result = fixedAmountVoucher.discount(originalPrice); + int result = discountPolicy.discount(originalPrice); // then assertThat(result).isEqualTo(expected); diff --git a/src/test/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountVoucherTest.java b/src/test/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicyTest.java similarity index 79% rename from src/test/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountVoucherTest.java rename to src/test/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicyTest.java index 3270283d76..03811aa36a 100644 --- a/src/test/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountVoucherTest.java +++ b/src/test/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicyTest.java @@ -8,7 +8,7 @@ import static org.assertj.core.api.Assertions.*; -class PercentDiscountVoucherTest { +class PercentDiscountPolicyTest { @Nested @DisplayName("할인률을 검증한다.") @@ -19,7 +19,7 @@ class validationAmount { @DisplayName("할인률이 1에서 100 사이인 경우 예외가 발생하지 않는다.") void isBetween1And100(int amount) { // when & then - assertThatCode(() -> new PercentDiscountVoucher(amount)) + assertThatCode(() -> new PercentDiscountPolicy(amount)) .doesNotThrowAnyException(); } @@ -28,9 +28,7 @@ void isBetween1And100(int amount) { @DisplayName("할인률이 1에서 100 사이가 아닌 경우 예외가 발생한다.") void isNotBetween1And100(int amount) { // when & then - assertThatThrownBy(() -> { - new PercentDiscountVoucher(amount); - }) + assertThatThrownBy(() -> new PercentDiscountPolicy(amount)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("The discount percentage must be between 1 and 100%."); } @@ -41,10 +39,10 @@ void isNotBetween1And100(int amount) { @DisplayName("정률 할인을 적용한다.") void discount(int amount, int expected) { // given - PercentDiscountVoucher percentDiscountVoucher = new PercentDiscountVoucher(amount); + DiscountPolicy discountPolicy = new PercentDiscountPolicy(amount); // when - int result = percentDiscountVoucher.discount(10000); + int result = discountPolicy.discount(10000); // then assertThat(result).isEqualTo(expected); diff --git a/src/test/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepositoryTest.java b/src/test/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepositoryTest.java index 242148dbb2..5aa322d571 100644 --- a/src/test/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepositoryTest.java +++ b/src/test/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepositoryTest.java @@ -1,8 +1,6 @@ package com.programmers.vouchermanagement.voucher.infrastructure; -import com.programmers.vouchermanagement.voucher.domain.FixedAmountVoucher; -import com.programmers.vouchermanagement.voucher.domain.PercentDiscountVoucher; -import com.programmers.vouchermanagement.voucher.domain.Voucher; +import com.programmers.vouchermanagement.voucher.domain.*; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -18,7 +16,8 @@ class MemoryVoucherRepositoryTest { @DisplayName("바우처를 저장한다.") void save() { // given - FixedAmountVoucher voucher = new FixedAmountVoucher(100); + DiscountType discountType = DiscountType.FIX; + Voucher voucher = discountType.createVoucher(100); // when Voucher result = memoryVoucherRepository.save(voucher); @@ -31,8 +30,10 @@ void save() { @DisplayName("바우처를 모두 조회한다.") void findAll() { // given - FixedAmountVoucher voucher1 = new FixedAmountVoucher(100); - PercentDiscountVoucher voucher2 = new PercentDiscountVoucher(30); + DiscountPolicy discountPolicy1 = new FixedAmountDiscountPolicy(5000); + DiscountPolicy discountPolicy2 = new PercentDiscountPolicy(10); + Voucher voucher1 = new Voucher(discountPolicy1); + Voucher voucher2 = new Voucher(discountPolicy2); memoryVoucherRepository.save(voucher1); memoryVoucherRepository.save(voucher2); From 66a172419fa489df0dc9c08015ffe3908115dd4b Mon Sep 17 00:00:00 2001 From: Yiseull Date: Wed, 5 Jul 2023 00:49:31 +0900 Subject: [PATCH 10/28] =?UTF-8?q?fix:=20=EB=B0=94=EC=9A=B0=EC=B2=98=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=ED=8F=AC=EB=A7=B7=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CommandLineController.java | 8 +++-- .../vouchermanagement/view/Console.java | 14 +++++---- .../voucher/application/VoucherDto.java | 14 +++++++++ .../voucher/application/VoucherService.java | 14 +++++---- .../voucher/domain/DiscountPolicy.java | 6 ++-- .../voucher/domain/DiscountType.java | 11 +++---- .../domain/FixedAmountDiscountPolicy.java | 7 ++++- .../voucher/domain/PercentDiscountPolicy.java | 7 ++++- .../voucher/domain/Voucher.java | 8 ++++- .../voucher/dto/VoucherDto.java | 29 ------------------- .../presentation/VoucherController.java | 8 +++-- .../application/VoucherServiceTest.java | 13 ++++----- .../MemoryVoucherRepositoryTest.java | 6 ++-- 13 files changed, 77 insertions(+), 68 deletions(-) create mode 100644 src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherDto.java delete mode 100644 src/main/java/com/programmers/vouchermanagement/voucher/dto/VoucherDto.java diff --git a/src/main/java/com/programmers/vouchermanagement/CommandLineController.java b/src/main/java/com/programmers/vouchermanagement/CommandLineController.java index f9f19d2617..f04059874c 100644 --- a/src/main/java/com/programmers/vouchermanagement/CommandLineController.java +++ b/src/main/java/com/programmers/vouchermanagement/CommandLineController.java @@ -3,13 +3,15 @@ import com.programmers.vouchermanagement.view.Command; import com.programmers.vouchermanagement.view.Console; import com.programmers.vouchermanagement.voucher.domain.DiscountType; -import com.programmers.vouchermanagement.voucher.dto.VoucherDto; +import com.programmers.vouchermanagement.voucher.application.VoucherDto; import com.programmers.vouchermanagement.voucher.presentation.VoucherController; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Controller; +import java.util.List; + @Slf4j @Controller @RequiredArgsConstructor @@ -38,11 +40,11 @@ private boolean isRunning() { case CREATE -> { DiscountType discountType = DiscountType.from(Console.selectDiscountType()); int discountAmount = Console.inputDiscountAmount(); - VoucherDto.Request request = new VoucherDto.Request(discountType, discountAmount); + VoucherDto request = new VoucherDto(discountType, discountAmount); voucherController.createVoucher(request); } case LIST-> { - VoucherDto.Response vouchers = voucherController.getVouchers(); + List vouchers = voucherController.getVouchers(); Console.outputVouchers(vouchers); } case EXIT -> { diff --git a/src/main/java/com/programmers/vouchermanagement/view/Console.java b/src/main/java/com/programmers/vouchermanagement/view/Console.java index a0e1a21fb5..e93b5c11b4 100644 --- a/src/main/java/com/programmers/vouchermanagement/view/Console.java +++ b/src/main/java/com/programmers/vouchermanagement/view/Console.java @@ -1,9 +1,9 @@ package com.programmers.vouchermanagement.view; -import com.programmers.vouchermanagement.voucher.dto.VoucherDto; +import com.programmers.vouchermanagement.voucher.application.VoucherDto; +import java.util.List; import java.util.Scanner; -import java.util.stream.Collectors; public class Console { @@ -49,11 +49,13 @@ private static int inputInt() { return inputValue; } - public static void outputVouchers(VoucherDto.Response vouchers) { + public static void outputVouchers(List vouchers) { System.out.println("\nThis is a list of vouchers"); - System.out.println(vouchers.voucherName().stream() - .map(voucher -> voucher + System.lineSeparator()) - .collect(Collectors.joining())); + StringBuilder builder = new StringBuilder(); + vouchers.stream() + .map(voucher -> "Voucher Type: " + voucher.discountType().getName() + ", Amount: " + voucher.amount()) + .forEach(builder::append); + System.out.println(builder); } public static void outputErrorMessage(String errorMessage) { diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherDto.java b/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherDto.java new file mode 100644 index 0000000000..aa48ba3cf4 --- /dev/null +++ b/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherDto.java @@ -0,0 +1,14 @@ +package com.programmers.vouchermanagement.voucher.application; + +import com.programmers.vouchermanagement.voucher.domain.DiscountPolicy; +import com.programmers.vouchermanagement.voucher.domain.DiscountType; +import com.programmers.vouchermanagement.voucher.domain.Voucher; + +public record VoucherDto(DiscountType discountType, int amount) { + + public static VoucherDto toDto(Voucher voucher) { + DiscountType discountType = voucher.getDiscountType(); + DiscountPolicy discountPolicy = voucher.getDiscountPolicy(); + return new VoucherDto(discountType, discountPolicy.getAmount()); + } +} diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherService.java b/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherService.java index 0415e5ccf7..69a87269f4 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherService.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherService.java @@ -3,12 +3,12 @@ import com.programmers.vouchermanagement.voucher.domain.DiscountType; import com.programmers.vouchermanagement.voucher.domain.Voucher; import com.programmers.vouchermanagement.voucher.domain.VoucherRepository; -import com.programmers.vouchermanagement.voucher.dto.VoucherDto; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.util.List; +import java.util.stream.Collectors; @Slf4j @Service @@ -17,16 +17,18 @@ public class VoucherService { private final VoucherRepository voucherRepository; - public Voucher createVoucher(VoucherDto.Request request) { + public Voucher createVoucher(VoucherDto request) { DiscountType discountType = request.discountType(); - int amount = request.discountAmount(); + int amount = request.amount(); Voucher voucher = discountType.createVoucher(amount); - log.info("Create Voucher! DiscountType: {}, DiscountAmount: {}", voucher.getClass().getSimpleName(), request.discountAmount()); + log.info("Create Voucher! DiscountType: {}, DiscountAmount: {}", voucher.getClass().getSimpleName(), request.amount()); return voucherRepository.save(voucher); } - public VoucherDto.Response getVouchers() { + public List getVouchers() { List vouchers = voucherRepository.findAll(); - return VoucherDto.Response.toDto(vouchers); + return vouchers.stream() + .map(VoucherDto::toDto) + .collect(Collectors.toList()); } } diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountPolicy.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountPolicy.java index 736517bc54..a8f1696989 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountPolicy.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountPolicy.java @@ -1,6 +1,8 @@ package com.programmers.vouchermanagement.voucher.domain; -public abstract class DiscountPolicy { +public interface DiscountPolicy { - abstract int discount(int originalPrice); + int getAmount(); + + int discount(int originalPrice); } diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountType.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountType.java index f8fd42fb6e..4fd6c14db3 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountType.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountType.java @@ -2,17 +2,18 @@ import java.util.Collections; import java.util.Map; +import java.util.function.BiFunction; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; public enum DiscountType { - FIX("fix", (amount) -> new Voucher(new FixedAmountDiscountPolicy(amount))), - PERCENT("percent", (amount) -> new Voucher(new PercentDiscountPolicy(amount))); + FIX("fix", (amount, discountType) -> new Voucher(new FixedAmountDiscountPolicy(amount), discountType)), + PERCENT("percent", (amount, discountType) -> new Voucher(new PercentDiscountPolicy(amount), discountType)); private final String name; - private final Function function; + private final BiFunction function; private static final Map DISCOUNT_TYPE_MAP; static { @@ -20,7 +21,7 @@ public enum DiscountType { .collect(Collectors.toMap(DiscountType::getName, Function.identity()))); } - DiscountType(String name, Function function) { + DiscountType(String name, BiFunction function) { this.name = name; this.function = function; } @@ -37,6 +38,6 @@ public static DiscountType from(String name) { } public Voucher createVoucher(int amount) { - return function.apply(amount); + return function.apply(amount, this); } } diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicy.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicy.java index 07b408b1e1..1d1a89ad17 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicy.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicy.java @@ -1,6 +1,6 @@ package com.programmers.vouchermanagement.voucher.domain; -public class FixedAmountDiscountPolicy extends DiscountPolicy { +public class FixedAmountDiscountPolicy implements DiscountPolicy { public static final int MIN_AMOUNT = 1; @@ -17,6 +17,11 @@ private void validationAmount(int amount) { } } + @Override + public int getAmount() { + return amount; + } + @Override public int discount(int originalPrice) { if (amount > originalPrice) { diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicy.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicy.java index ccdcee7690..de6c294f40 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicy.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicy.java @@ -2,7 +2,7 @@ import java.math.BigDecimal; -public class PercentDiscountPolicy extends DiscountPolicy { +public class PercentDiscountPolicy implements DiscountPolicy { public static final int MIN_PERCENT = 1; public static final int MAX_PERCENT = 100; @@ -20,6 +20,11 @@ private void validationAmount(int amount) { } } + @Override + public int getAmount() { + return amount; + } + @Override public int discount(int originalPrice) { int discountedAmount = calculateDiscountedAmount(originalPrice); diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/Voucher.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/Voucher.java index b70f183f82..6dc40f4312 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/Voucher.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/Voucher.java @@ -6,10 +6,12 @@ public class Voucher { private final UUID id; private final DiscountPolicy discountPolicy; + private final DiscountType discountType; - public Voucher(DiscountPolicy discountPolicy) { + public Voucher(DiscountPolicy discountPolicy, DiscountType discountType) { this.id = UUID.randomUUID(); this.discountPolicy = discountPolicy; + this.discountType = discountType; } public UUID getId() { @@ -20,6 +22,10 @@ public DiscountPolicy getDiscountPolicy() { return discountPolicy; } + public DiscountType getDiscountType() { + return discountType; + } + public int discount(int originalPrice) { return discountPolicy.discount(originalPrice); } diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/dto/VoucherDto.java b/src/main/java/com/programmers/vouchermanagement/voucher/dto/VoucherDto.java deleted file mode 100644 index 0e20dd578c..0000000000 --- a/src/main/java/com/programmers/vouchermanagement/voucher/dto/VoucherDto.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.programmers.vouchermanagement.voucher.dto; - -import com.programmers.vouchermanagement.voucher.domain.DiscountType; -import com.programmers.vouchermanagement.voucher.domain.Voucher; - -import java.util.List; -import java.util.stream.Collectors; - -public class VoucherDto { - - public record Request(DiscountType discountType, int discountAmount) { - } - - public record Response(List voucherName) { - - @Override - public List voucherName() { - return voucherName; - } - - public static VoucherDto.Response toDto(List vouchers) { - List vourcherList = vouchers.stream() - .map(voucher -> voucher.getClass().getSimpleName()) - .collect(Collectors.toList()); - return new VoucherDto.Response(vourcherList); - } - } - -} diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/presentation/VoucherController.java b/src/main/java/com/programmers/vouchermanagement/voucher/presentation/VoucherController.java index 41d0733eb9..438005260b 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/presentation/VoucherController.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/presentation/VoucherController.java @@ -1,21 +1,23 @@ package com.programmers.vouchermanagement.voucher.presentation; import com.programmers.vouchermanagement.voucher.application.VoucherService; -import com.programmers.vouchermanagement.voucher.dto.VoucherDto; +import com.programmers.vouchermanagement.voucher.application.VoucherDto; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Controller; +import java.util.List; + @Controller @RequiredArgsConstructor public class VoucherController { private final VoucherService voucherService; - public void createVoucher(VoucherDto.Request request) { + public void createVoucher(VoucherDto request) { voucherService.createVoucher(request); } - public VoucherDto.Response getVouchers() { + public List getVouchers() { return voucherService.getVouchers(); } } diff --git a/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherServiceTest.java b/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherServiceTest.java index 3eda61b647..1c2c217f1b 100644 --- a/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherServiceTest.java +++ b/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherServiceTest.java @@ -1,7 +1,6 @@ package com.programmers.vouchermanagement.voucher.application; import com.programmers.vouchermanagement.voucher.domain.*; -import com.programmers.vouchermanagement.voucher.dto.VoucherDto; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -30,9 +29,9 @@ class VoucherServiceTest { @DisplayName("바우처를 생성한다.") void createVoucher() { // given - VoucherDto.Request request = new VoucherDto.Request(DiscountType.FIX, 5000); + VoucherDto request = new VoucherDto(DiscountType.FIX, 5000); DiscountType discountType = request.discountType(); - int amount = request.discountAmount(); + int amount = request.amount(); Voucher voucher = discountType.createVoucher(amount); given(voucherRepository.save(any(Voucher.class))) @@ -52,17 +51,17 @@ void createVoucher() { @DisplayName("바우처를 모두 조회한다.") void getVouchers() { // given - Voucher voucher1 = new Voucher(new FixedAmountDiscountPolicy(5000)); - Voucher voucher2 = new Voucher(new PercentDiscountPolicy(10)); + Voucher voucher1 = new Voucher(new FixedAmountDiscountPolicy(5000), DiscountType.FIX); + Voucher voucher2 = new Voucher(new PercentDiscountPolicy(10), DiscountType.PERCENT); given(voucherRepository.findAll()) .willReturn(List.of(voucher1, voucher2)); // when - VoucherDto.Response result = voucherService.getVouchers(); + List result = voucherService.getVouchers(); // then - assertThat(result.voucherName()).hasSize(2); + assertThat(result).hasSize(2); // verify verify(voucherRepository, times(1)).findAll(); diff --git a/src/test/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepositoryTest.java b/src/test/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepositoryTest.java index 5aa322d571..8aafcac190 100644 --- a/src/test/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepositoryTest.java +++ b/src/test/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepositoryTest.java @@ -30,10 +30,8 @@ void save() { @DisplayName("바우처를 모두 조회한다.") void findAll() { // given - DiscountPolicy discountPolicy1 = new FixedAmountDiscountPolicy(5000); - DiscountPolicy discountPolicy2 = new PercentDiscountPolicy(10); - Voucher voucher1 = new Voucher(discountPolicy1); - Voucher voucher2 = new Voucher(discountPolicy2); + Voucher voucher1 = new Voucher(new FixedAmountDiscountPolicy(5000), DiscountType.FIX); + Voucher voucher2 = new Voucher(new PercentDiscountPolicy(10), DiscountType.PERCENT); memoryVoucherRepository.save(voucher1); memoryVoucherRepository.save(voucher2); From 087dc0d3dc7f8cdda9e67c4fd427abf9017ebd30 Mon Sep 17 00:00:00 2001 From: Yiseull Date: Wed, 5 Jul 2023 02:39:34 +0900 Subject: [PATCH 11/28] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=8B=A4=ED=96=89=20=EC=88=9C=EC=84=9C=EC=97=90=20=EC=98=81?= =?UTF-8?q?=ED=96=A5=20=EC=97=86=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD,?= =?UTF-8?q?=20=EC=8B=A4=EC=A0=9C=20=EB=B0=94=EC=9A=B0=EC=B2=98=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../voucher/domain/VoucherRepository.java | 4 ++++ .../infrastructure/MemoryVoucherRepository.java | 14 ++++++++++---- .../MemoryVoucherRepositoryTest.java | 13 +++++++++---- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/VoucherRepository.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/VoucherRepository.java index d2f385ca65..aecbab48e0 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/VoucherRepository.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/VoucherRepository.java @@ -1,10 +1,14 @@ package com.programmers.vouchermanagement.voucher.domain; import java.util.List; +import java.util.Optional; +import java.util.UUID; public interface VoucherRepository { Voucher save(Voucher voucher); + Optional findById(UUID id); + List findAll(); } diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepository.java b/src/main/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepository.java index 41bd15da65..50f5244f0d 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepository.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepository.java @@ -4,10 +4,7 @@ import com.programmers.vouchermanagement.voucher.domain.VoucherRepository; import org.springframework.stereotype.Repository; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.UUID; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; @Repository @@ -21,8 +18,17 @@ public Voucher save(Voucher voucher) { return voucher; } + @Override + public Optional findById(UUID id) { + return Optional.ofNullable(storage.get(id)); + } + @Override public List findAll() { return new ArrayList<>(storage.values()); } + + public void clearStorage() { + storage.clear(); + } } diff --git a/src/test/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepositoryTest.java b/src/test/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepositoryTest.java index 8aafcac190..543ae1ed52 100644 --- a/src/test/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepositoryTest.java +++ b/src/test/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepositoryTest.java @@ -1,8 +1,7 @@ package com.programmers.vouchermanagement.voucher.infrastructure; import com.programmers.vouchermanagement.voucher.domain.*; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.*; import java.util.List; @@ -12,6 +11,11 @@ class MemoryVoucherRepositoryTest { MemoryVoucherRepository memoryVoucherRepository = new MemoryVoucherRepository(); + @AfterEach + void afterEach() { + memoryVoucherRepository.clearStorage(); + } + @Test @DisplayName("바우처를 저장한다.") void save() { @@ -20,10 +24,11 @@ void save() { Voucher voucher = discountType.createVoucher(100); // when - Voucher result = memoryVoucherRepository.save(voucher); + memoryVoucherRepository.save(voucher); // then - assertThat(result.getId()).isEqualTo(voucher.getId()); + Voucher result = memoryVoucherRepository.findById(voucher.getId()).get(); + assertThat(result).isEqualTo(voucher); } @Test From 29d1e4501e73d1ff5f48b0c6e1ab4b613bd3cb2d Mon Sep 17 00:00:00 2001 From: Yiseull Date: Wed, 5 Jul 2023 02:46:59 +0900 Subject: [PATCH 12/28] =?UTF-8?q?test:=20DisplayName=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../voucher/domain/FixedAmountDiscountPolicyTest.java | 4 ++-- .../voucher/domain/PercentDiscountPolicyTest.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicyTest.java b/src/test/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicyTest.java index 5af17f7ae9..ae97d5caf4 100644 --- a/src/test/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicyTest.java +++ b/src/test/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicyTest.java @@ -11,8 +11,8 @@ class FixedAmountDiscountPolicyTest { @Nested - @DisplayName("할인 금액을 검증한다.") - class validationAmount { + @DisplayName("정액 할인 정책을 생성한다.") + class createFixedAmountDiscountPolicy { @ParameterizedTest @ValueSource(ints = {1, 10}) diff --git a/src/test/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicyTest.java b/src/test/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicyTest.java index 03811aa36a..e8b6e9640a 100644 --- a/src/test/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicyTest.java +++ b/src/test/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicyTest.java @@ -11,8 +11,8 @@ class PercentDiscountPolicyTest { @Nested - @DisplayName("할인률을 검증한다.") - class validationAmount { + @DisplayName("정률 할인 정책을 생성한다.") + class createPercentDiscountPolicy { @ParameterizedTest @ValueSource(ints = {1, 50, 100}) From 37753671470b08fab59e285e15171e7602927213 Mon Sep 17 00:00:00 2001 From: Yiseull Date: Wed, 5 Jul 2023 02:54:11 +0900 Subject: [PATCH 13/28] =?UTF-8?q?refactor:=20=EB=AA=85=ED=99=95=ED=95=9C?= =?UTF-8?q?=20=ED=95=84=EB=93=9C=EB=AA=85=EC=9C=BC=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vouchermanagement/voucher/domain/DiscountType.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountType.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountType.java index 4fd6c14db3..aa70ec2170 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountType.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountType.java @@ -13,7 +13,7 @@ public enum DiscountType { PERCENT("percent", (amount, discountType) -> new Voucher(new PercentDiscountPolicy(amount), discountType)); private final String name; - private final BiFunction function; + private final BiFunction voucherCreationFunction; private static final Map DISCOUNT_TYPE_MAP; static { @@ -21,9 +21,9 @@ public enum DiscountType { .collect(Collectors.toMap(DiscountType::getName, Function.identity()))); } - DiscountType(String name, BiFunction function) { + DiscountType(String name, BiFunction voucherCreationFunction) { this.name = name; - this.function = function; + this.voucherCreationFunction = voucherCreationFunction; } public String getName() { @@ -38,6 +38,6 @@ public static DiscountType from(String name) { } public Voucher createVoucher(int amount) { - return function.apply(amount, this); + return voucherCreationFunction.apply(amount, this); } } From a6f5391c17cad0456409464e83ae646b1323c930 Mon Sep 17 00:00:00 2001 From: Yiseul Park Date: Thu, 6 Jul 2023 22:34:44 +0900 Subject: [PATCH 14/28] =?UTF-8?q?refactor:=20Voucher=20=EC=97=90=EC=84=9C?= =?UTF-8?q?=20DiscountType=20=ED=95=84=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vouchermanagement/voucher/application/VoucherDto.java | 3 +-- .../vouchermanagement/voucher/domain/DiscountPolicy.java | 2 ++ .../vouchermanagement/voucher/domain/DiscountType.java | 4 ++-- .../voucher/domain/FixedAmountDiscountPolicy.java | 5 +++++ .../voucher/domain/PercentDiscountPolicy.java | 5 +++++ .../vouchermanagement/voucher/domain/Voucher.java | 8 +------- .../voucher/application/VoucherServiceTest.java | 4 ++-- .../infrastructure/MemoryVoucherRepositoryTest.java | 4 ++-- 8 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherDto.java b/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherDto.java index aa48ba3cf4..754004b8b2 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherDto.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherDto.java @@ -7,8 +7,7 @@ public record VoucherDto(DiscountType discountType, int amount) { public static VoucherDto toDto(Voucher voucher) { - DiscountType discountType = voucher.getDiscountType(); DiscountPolicy discountPolicy = voucher.getDiscountPolicy(); - return new VoucherDto(discountType, discountPolicy.getAmount()); + return new VoucherDto(discountPolicy.getType(), discountPolicy.getAmount()); } } diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountPolicy.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountPolicy.java index a8f1696989..9766ddb3f2 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountPolicy.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountPolicy.java @@ -4,5 +4,7 @@ public interface DiscountPolicy { int getAmount(); + DiscountType getType(); + int discount(int originalPrice); } diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountType.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountType.java index aa70ec2170..27331b7e91 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountType.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountType.java @@ -9,8 +9,8 @@ public enum DiscountType { - FIX("fix", (amount, discountType) -> new Voucher(new FixedAmountDiscountPolicy(amount), discountType)), - PERCENT("percent", (amount, discountType) -> new Voucher(new PercentDiscountPolicy(amount), discountType)); + FIX("fix", (amount, discountType) -> new Voucher(new FixedAmountDiscountPolicy(amount))), + PERCENT("percent", (amount, discountType) -> new Voucher(new PercentDiscountPolicy(amount))); private final String name; private final BiFunction voucherCreationFunction; diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicy.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicy.java index 1d1a89ad17..21b3cab72e 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicy.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicy.java @@ -22,6 +22,11 @@ public int getAmount() { return amount; } + @Override + public DiscountType getType() { + return DiscountType.FIX; + } + @Override public int discount(int originalPrice) { if (amount > originalPrice) { diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicy.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicy.java index de6c294f40..dff122c3a9 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicy.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicy.java @@ -25,6 +25,11 @@ public int getAmount() { return amount; } + @Override + public DiscountType getType() { + return DiscountType.PERCENT; + } + @Override public int discount(int originalPrice) { int discountedAmount = calculateDiscountedAmount(originalPrice); diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/Voucher.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/Voucher.java index 6dc40f4312..b70f183f82 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/Voucher.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/Voucher.java @@ -6,12 +6,10 @@ public class Voucher { private final UUID id; private final DiscountPolicy discountPolicy; - private final DiscountType discountType; - public Voucher(DiscountPolicy discountPolicy, DiscountType discountType) { + public Voucher(DiscountPolicy discountPolicy) { this.id = UUID.randomUUID(); this.discountPolicy = discountPolicy; - this.discountType = discountType; } public UUID getId() { @@ -22,10 +20,6 @@ public DiscountPolicy getDiscountPolicy() { return discountPolicy; } - public DiscountType getDiscountType() { - return discountType; - } - public int discount(int originalPrice) { return discountPolicy.discount(originalPrice); } diff --git a/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherServiceTest.java b/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherServiceTest.java index 1c2c217f1b..7b61e0aa20 100644 --- a/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherServiceTest.java +++ b/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherServiceTest.java @@ -51,8 +51,8 @@ void createVoucher() { @DisplayName("바우처를 모두 조회한다.") void getVouchers() { // given - Voucher voucher1 = new Voucher(new FixedAmountDiscountPolicy(5000), DiscountType.FIX); - Voucher voucher2 = new Voucher(new PercentDiscountPolicy(10), DiscountType.PERCENT); + Voucher voucher1 = new Voucher(new FixedAmountDiscountPolicy(5000)); + Voucher voucher2 = new Voucher(new PercentDiscountPolicy(10)); given(voucherRepository.findAll()) .willReturn(List.of(voucher1, voucher2)); diff --git a/src/test/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepositoryTest.java b/src/test/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepositoryTest.java index 543ae1ed52..f2708b3575 100644 --- a/src/test/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepositoryTest.java +++ b/src/test/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepositoryTest.java @@ -35,8 +35,8 @@ void save() { @DisplayName("바우처를 모두 조회한다.") void findAll() { // given - Voucher voucher1 = new Voucher(new FixedAmountDiscountPolicy(5000), DiscountType.FIX); - Voucher voucher2 = new Voucher(new PercentDiscountPolicy(10), DiscountType.PERCENT); + Voucher voucher1 = new Voucher(new FixedAmountDiscountPolicy(5000)); + Voucher voucher2 = new Voucher(new PercentDiscountPolicy(10)); memoryVoucherRepository.save(voucher1); memoryVoucherRepository.save(voucher2); From 6cc9f1530206a44089f4b3ee98f5d2d698bcfe56 Mon Sep 17 00:00:00 2001 From: Yiseul Park Date: Fri, 7 Jul 2023 01:13:26 +0900 Subject: [PATCH 15/28] =?UTF-8?q?feat:=20VoucherRepository=20Update,=20Del?= =?UTF-8?q?ete=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../voucher/domain/Voucher.java | 11 +++- .../voucher/domain/VoucherRepository.java | 4 ++ .../MemoryVoucherRepository.java | 11 ++++ .../MemoryVoucherRepositoryTest.java | 58 +++++++++++++++++-- 4 files changed, 79 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/Voucher.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/Voucher.java index b70f183f82..8be7e47a68 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/Voucher.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/Voucher.java @@ -5,13 +5,18 @@ public class Voucher { private final UUID id; - private final DiscountPolicy discountPolicy; + private DiscountPolicy discountPolicy; public Voucher(DiscountPolicy discountPolicy) { this.id = UUID.randomUUID(); this.discountPolicy = discountPolicy; } + public Voucher(UUID id, DiscountPolicy discountPolicy) { + this.id = id; + this.discountPolicy = discountPolicy; + } + public UUID getId() { return id; } @@ -23,4 +28,8 @@ public DiscountPolicy getDiscountPolicy() { public int discount(int originalPrice) { return discountPolicy.discount(originalPrice); } + + public void changeDiscountPolicy(DiscountPolicy discountPolicy) { + this.discountPolicy = discountPolicy; + } } diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/VoucherRepository.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/VoucherRepository.java index aecbab48e0..d10a664494 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/VoucherRepository.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/VoucherRepository.java @@ -11,4 +11,8 @@ public interface VoucherRepository { Optional findById(UUID id); List findAll(); + + void update(Voucher voucher); + + void deleteById(UUID id); } diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepository.java b/src/main/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepository.java index 50f5244f0d..7d68e128a5 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepository.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepository.java @@ -28,6 +28,17 @@ public List findAll() { return new ArrayList<>(storage.values()); } + @Override + public void update(Voucher voucher) { + deleteById(voucher.getId()); + save(voucher); + } + + @Override + public void deleteById(UUID id) { + storage.remove(id); + } + public void clearStorage() { storage.clear(); } diff --git a/src/test/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepositoryTest.java b/src/test/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepositoryTest.java index f2708b3575..6f841ef025 100644 --- a/src/test/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepositoryTest.java +++ b/src/test/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepositoryTest.java @@ -1,9 +1,15 @@ package com.programmers.vouchermanagement.voucher.infrastructure; -import com.programmers.vouchermanagement.voucher.domain.*; -import org.junit.jupiter.api.*; +import com.programmers.vouchermanagement.voucher.domain.FixedAmountDiscountPolicy; +import com.programmers.vouchermanagement.voucher.domain.PercentDiscountPolicy; +import com.programmers.vouchermanagement.voucher.domain.Voucher; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; import java.util.List; +import java.util.Optional; +import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; @@ -20,8 +26,7 @@ void afterEach() { @DisplayName("바우처를 저장한다.") void save() { // given - DiscountType discountType = DiscountType.FIX; - Voucher voucher = discountType.createVoucher(100); + Voucher voucher = new Voucher(new FixedAmountDiscountPolicy(5000)); // when memoryVoucherRepository.save(voucher); @@ -31,6 +36,21 @@ void save() { assertThat(result).isEqualTo(voucher); } + @Test + @DisplayName("Id로 바우처를 조회한다.") + void findById() { + // given + UUID id = UUID.randomUUID(); + Voucher voucher = new Voucher(id, new FixedAmountDiscountPolicy(5000)); + memoryVoucherRepository.save(voucher); + + // when + Voucher result = memoryVoucherRepository.findById(voucher.getId()).get(); + + // then + assertThat(result).isEqualTo(voucher); + } + @Test @DisplayName("바우처를 모두 조회한다.") void findAll() { @@ -47,4 +67,34 @@ void findAll() { // then assertThat(result).hasSize(2); } + + @Test + @DisplayName("바우처를 업데이트한다.") + void update() { + // given + Voucher voucher = new Voucher(new FixedAmountDiscountPolicy(5000)); + memoryVoucherRepository.save(voucher); + voucher.changeDiscountPolicy(new PercentDiscountPolicy(10)); + + // when + memoryVoucherRepository.update(voucher); + + // then + assertThat(voucher.getDiscountPolicy()).isInstanceOf(PercentDiscountPolicy.class); + assertThat(voucher.getDiscountPolicy().getAmount()).isEqualTo(10); + } + + @Test + @DisplayName("바우처를 삭제한다.") + void deleteById() { + // given + Voucher voucher = new Voucher(new FixedAmountDiscountPolicy(5000)); + + // when + memoryVoucherRepository.deleteById(voucher.getId()); + + // then + Optional result = memoryVoucherRepository.findById(voucher.getId()); + assertThat(result).isEmpty(); + } } \ No newline at end of file From 9d830b74aa00005c0b5b7268da5551b900522953 Mon Sep 17 00:00:00 2001 From: Yiseul Park Date: Fri, 7 Jul 2023 10:48:25 +0900 Subject: [PATCH 16/28] =?UTF-8?q?refactor:=20=ED=95=A0=EC=9D=B8=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=EC=97=90=20=EB=A7=9E=EB=8A=94=20=EB=B0=94?= =?UTF-8?q?=EC=9A=B0=EC=B2=98=20=EB=8C=80=EC=8B=A0=20=ED=95=A0=EC=9D=B8=20?= =?UTF-8?q?=EC=A0=95=EC=B1=85=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../voucher/application/VoucherService.java | 7 ++++--- .../voucher/domain/DiscountType.java | 13 ++++++------- .../voucher/application/VoucherServiceTest.java | 3 ++- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherService.java b/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherService.java index 69a87269f4..9dc0ad1e9f 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherService.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherService.java @@ -1,5 +1,6 @@ package com.programmers.vouchermanagement.voucher.application; +import com.programmers.vouchermanagement.voucher.domain.DiscountPolicy; import com.programmers.vouchermanagement.voucher.domain.DiscountType; import com.programmers.vouchermanagement.voucher.domain.Voucher; import com.programmers.vouchermanagement.voucher.domain.VoucherRepository; @@ -8,7 +9,6 @@ import org.springframework.stereotype.Service; import java.util.List; -import java.util.stream.Collectors; @Slf4j @Service @@ -20,7 +20,8 @@ public class VoucherService { public Voucher createVoucher(VoucherDto request) { DiscountType discountType = request.discountType(); int amount = request.amount(); - Voucher voucher = discountType.createVoucher(amount); + DiscountPolicy discountPolicy = discountType.createDiscountPolicy(amount); + Voucher voucher = new Voucher(discountPolicy); log.info("Create Voucher! DiscountType: {}, DiscountAmount: {}", voucher.getClass().getSimpleName(), request.amount()); return voucherRepository.save(voucher); } @@ -29,6 +30,6 @@ public List getVouchers() { List vouchers = voucherRepository.findAll(); return vouchers.stream() .map(VoucherDto::toDto) - .collect(Collectors.toList()); + .toList(); } } diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountType.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountType.java index 27331b7e91..9701a15fe2 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountType.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountType.java @@ -2,18 +2,17 @@ import java.util.Collections; import java.util.Map; -import java.util.function.BiFunction; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; public enum DiscountType { - FIX("fix", (amount, discountType) -> new Voucher(new FixedAmountDiscountPolicy(amount))), - PERCENT("percent", (amount, discountType) -> new Voucher(new PercentDiscountPolicy(amount))); + FIX("fix", FixedAmountDiscountPolicy::new), + PERCENT("percent", PercentDiscountPolicy::new); private final String name; - private final BiFunction voucherCreationFunction; + private final Function voucherCreationFunction; private static final Map DISCOUNT_TYPE_MAP; static { @@ -21,7 +20,7 @@ public enum DiscountType { .collect(Collectors.toMap(DiscountType::getName, Function.identity()))); } - DiscountType(String name, BiFunction voucherCreationFunction) { + DiscountType(String name, Function voucherCreationFunction) { this.name = name; this.voucherCreationFunction = voucherCreationFunction; } @@ -37,7 +36,7 @@ public static DiscountType from(String name) { throw new IllegalArgumentException("This discount type does not exist."); } - public Voucher createVoucher(int amount) { - return voucherCreationFunction.apply(amount, this); + public DiscountPolicy createDiscountPolicy(int amount) { + return voucherCreationFunction.apply(amount); } } diff --git a/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherServiceTest.java b/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherServiceTest.java index 7b61e0aa20..07e96ea642 100644 --- a/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherServiceTest.java +++ b/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherServiceTest.java @@ -32,7 +32,8 @@ void createVoucher() { VoucherDto request = new VoucherDto(DiscountType.FIX, 5000); DiscountType discountType = request.discountType(); int amount = request.amount(); - Voucher voucher = discountType.createVoucher(amount); + DiscountPolicy discountPolicy = discountType.createDiscountPolicy(amount); + Voucher voucher = new Voucher(discountPolicy); given(voucherRepository.save(any(Voucher.class))) .willReturn(voucher); From 9d86602b668d3a9c935333e0b806a54639582860 Mon Sep 17 00:00:00 2001 From: Yiseul Park Date: Fri, 7 Jul 2023 21:43:52 +0900 Subject: [PATCH 17/28] =?UTF-8?q?feat:=20=EB=B1=8C=EC=9A=B0=EC=B2=98=20?= =?UTF-8?q?=EB=A0=88=ED=8F=AC=EC=A7=80=ED=86=A0=EB=A6=AC=20JdbcTemplate=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=20&=20=ED=94=84=EB=A1=9C=ED=8C=8C=EC=9D=BC?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CommandLineController.java | 2 + .../domain/FixedAmountDiscountPolicy.java | 15 +++ .../voucher/domain/PercentDiscountPolicy.java | 15 +++ .../voucher/domain/Voucher.java | 19 ++++ .../JdbcTemplateVoucherRepository.java | 79 ++++++++++++++ .../MemoryVoucherRepository.java | 2 + src/main/resources/application-dev.yml | 2 + src/main/resources/application-test.yml | 15 +++ src/main/resources/application.yml | 14 +++ src/main/resources/schema.sql | 8 ++ .../JdbcTemplateVoucherRepositoryTest.java | 100 ++++++++++++++++++ 11 files changed, 271 insertions(+) create mode 100644 src/main/java/com/programmers/vouchermanagement/voucher/infrastructure/JdbcTemplateVoucherRepository.java create mode 100644 src/main/resources/application-dev.yml create mode 100644 src/main/resources/application-test.yml create mode 100644 src/main/resources/application.yml create mode 100644 src/main/resources/schema.sql create mode 100644 src/test/java/com/programmers/vouchermanagement/voucher/infrastructure/JdbcTemplateVoucherRepositoryTest.java diff --git a/src/main/java/com/programmers/vouchermanagement/CommandLineController.java b/src/main/java/com/programmers/vouchermanagement/CommandLineController.java index f04059874c..2a2b63dbe0 100644 --- a/src/main/java/com/programmers/vouchermanagement/CommandLineController.java +++ b/src/main/java/com/programmers/vouchermanagement/CommandLineController.java @@ -8,10 +8,12 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.CommandLineRunner; +import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Controller; import java.util.List; +@Profile("!test") @Slf4j @Controller @RequiredArgsConstructor diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicy.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicy.java index 21b3cab72e..0967988f0c 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicy.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicy.java @@ -34,4 +34,19 @@ public int discount(int originalPrice) { } return originalPrice - amount; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + FixedAmountDiscountPolicy that = (FixedAmountDiscountPolicy) o; + + return amount == that.amount; + } + + @Override + public int hashCode() { + return amount; + } } diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicy.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicy.java index dff122c3a9..62aa6fc290 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicy.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicy.java @@ -41,4 +41,19 @@ private int calculateDiscountedAmount(int originalPrice) { BigDecimal discountedAmount = percent.multiply(BigDecimal.valueOf(originalPrice)); return discountedAmount.intValue(); } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + PercentDiscountPolicy that = (PercentDiscountPolicy) o; + + return amount == that.amount; + } + + @Override + public int hashCode() { + return amount; + } } diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/Voucher.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/Voucher.java index 8be7e47a68..d145bf1a5c 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/Voucher.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/Voucher.java @@ -1,5 +1,6 @@ package com.programmers.vouchermanagement.voucher.domain; +import java.util.Objects; import java.util.UUID; public class Voucher { @@ -32,4 +33,22 @@ public int discount(int originalPrice) { public void changeDiscountPolicy(DiscountPolicy discountPolicy) { this.discountPolicy = discountPolicy; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Voucher voucher = (Voucher) o; + + if (!Objects.equals(id, voucher.id)) return false; + return Objects.equals(discountPolicy, voucher.discountPolicy); + } + + @Override + public int hashCode() { + int result = id != null ? id.hashCode() : 0; + result = 31 * result + (discountPolicy != null ? discountPolicy.hashCode() : 0); + return result; + } } diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/infrastructure/JdbcTemplateVoucherRepository.java b/src/main/java/com/programmers/vouchermanagement/voucher/infrastructure/JdbcTemplateVoucherRepository.java new file mode 100644 index 0000000000..2135600fc6 --- /dev/null +++ b/src/main/java/com/programmers/vouchermanagement/voucher/infrastructure/JdbcTemplateVoucherRepository.java @@ -0,0 +1,79 @@ +package com.programmers.vouchermanagement.voucher.infrastructure; + +import com.programmers.vouchermanagement.voucher.domain.DiscountPolicy; +import com.programmers.vouchermanagement.voucher.domain.DiscountType; +import com.programmers.vouchermanagement.voucher.domain.Voucher; +import com.programmers.vouchermanagement.voucher.domain.VoucherRepository; +import org.springframework.context.annotation.Primary; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Repository; + +import javax.sql.DataSource; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +@Primary +@Repository +public class JdbcTemplateVoucherRepository implements VoucherRepository { + + private final JdbcTemplate jdbcTemplate; + + public JdbcTemplateVoucherRepository(DataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + @Override + public Voucher save(Voucher voucher) { + String sql = "insert into voucher (id, type, amount) values (?, ?, ?)"; + jdbcTemplate.update(sql, + voucher.getId().toString(), + voucher.getDiscountPolicy().getType().toString(), + voucher.getDiscountPolicy().getAmount()); + return voucher; + } + + @Override + public Optional findById(UUID id) { + String sql = "select * from voucher where id = ?"; + try { + Voucher voucher = jdbcTemplate.queryForObject(sql, voucherRowMapper(), id.toString()); + return Optional.of(voucher); + } catch (EmptyResultDataAccessException e) { + return Optional.empty(); + } + } + + @Override + public List findAll() { + String sql = "select * from voucher"; + return jdbcTemplate.query(sql, voucherRowMapper()); + } + + @Override + public void update(Voucher voucher) { + String sql = "update voucher set type = ?, amount = ? where id = ?"; + jdbcTemplate.update(sql, + voucher.getDiscountPolicy().getType().toString(), + voucher.getDiscountPolicy().getAmount(), + voucher.getId().toString()); + } + + @Override + public void deleteById(UUID id) { + String sql = "delete from voucher where id = ?"; + jdbcTemplate.update(sql, id.toString()); + } + + private RowMapper voucherRowMapper() { + return (rs, rowNum) -> { + UUID id = UUID.fromString(rs.getString("id")); + DiscountType type = DiscountType.valueOf(rs.getString("type")); + int amount = rs.getInt("amount"); + DiscountPolicy discountPolicy = type.createDiscountPolicy(amount); + return new Voucher(id, discountPolicy); + }; + } +} diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepository.java b/src/main/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepository.java index 7d68e128a5..eb68b483a5 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepository.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/infrastructure/MemoryVoucherRepository.java @@ -2,11 +2,13 @@ import com.programmers.vouchermanagement.voucher.domain.Voucher; import com.programmers.vouchermanagement.voucher.domain.VoucherRepository; +import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Repository; import java.util.*; import java.util.concurrent.ConcurrentHashMap; +@Profile("dev") @Repository public class MemoryVoucherRepository implements VoucherRepository { diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml new file mode 100644 index 0000000000..ba07cd74d6 --- /dev/null +++ b/src/main/resources/application-dev.yml @@ -0,0 +1,2 @@ +version: "1.0" +description: "Memory" \ No newline at end of file diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml new file mode 100644 index 0000000000..d74e531b8b --- /dev/null +++ b/src/main/resources/application-test.yml @@ -0,0 +1,15 @@ +version: "2.0" +description: "JDBC H2" + +spring: + datasource: + driver-class-name: org.h2.Driver + url: jdbc:h2:mem:voucher_management + username: sa + password: + h2: + console: + enabled: true + sql: + init: + mode: always diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000000..acbd34efcb --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,14 @@ +version: "2.0" +description: "JDBC MySQL" + +spring: + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/voucher_management?serverTimezone=Asia/Seoul&characterEncoding=UTF-8 + username: root + password: password + + sql: + init: + platform: mysql + mode: always diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql new file mode 100644 index 0000000000..e23b485ecc --- /dev/null +++ b/src/main/resources/schema.sql @@ -0,0 +1,8 @@ +DROP TABLE IF EXISTS voucher; + +CREATE TABLE voucher ( + id VARCHAR(36), + type VARCHAR(20) NOT NULL, + amount int NOT NULL, + primary key (id) +); diff --git a/src/test/java/com/programmers/vouchermanagement/voucher/infrastructure/JdbcTemplateVoucherRepositoryTest.java b/src/test/java/com/programmers/vouchermanagement/voucher/infrastructure/JdbcTemplateVoucherRepositoryTest.java new file mode 100644 index 0000000000..e2bc7090a3 --- /dev/null +++ b/src/test/java/com/programmers/vouchermanagement/voucher/infrastructure/JdbcTemplateVoucherRepositoryTest.java @@ -0,0 +1,100 @@ +package com.programmers.vouchermanagement.voucher.infrastructure; + +import com.programmers.vouchermanagement.voucher.domain.FixedAmountDiscountPolicy; +import com.programmers.vouchermanagement.voucher.domain.PercentDiscountPolicy; +import com.programmers.vouchermanagement.voucher.domain.Voucher; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; + +@ActiveProfiles("test") +@SpringBootTest +@Transactional +class JdbcTemplateVoucherRepositoryTest { + + @Autowired + JdbcTemplateVoucherRepository voucherRepository; + + @Test + @DisplayName("바우처를 저장한다.") + void save() { + // given + Voucher voucher = new Voucher(new FixedAmountDiscountPolicy(5000)); + + // when + voucherRepository.save(voucher); + + // then + Voucher result = voucherRepository.findById(voucher.getId()).get(); + assertThat(result).isEqualTo(voucher); + } + + @Test + @DisplayName("Id로 바우처를 조회한다.") + void findById() { + // given + Voucher voucher = new Voucher(new FixedAmountDiscountPolicy(5000)); + voucherRepository.save(voucher); + + // when + Voucher result = voucherRepository.findById(voucher.getId()).get(); + + // then + assertThat(result).isEqualTo(voucher); + } + + @Test + @DisplayName("바우처를 모두 조회한다.") + void findAll() { + // given + Voucher voucher1 = new Voucher(new FixedAmountDiscountPolicy(5000)); + Voucher voucher2 = new Voucher(new PercentDiscountPolicy(10)); + + voucherRepository.save(voucher1); + voucherRepository.save(voucher2); + + // when + List result = voucherRepository.findAll(); + + // then + assertThat(result).hasSize(2); + } + + @Test + @DisplayName("바우처를 업데이트한다.") + void update() { + // given + Voucher voucher = new Voucher(new FixedAmountDiscountPolicy(5000)); + voucherRepository.save(voucher); + voucher.changeDiscountPolicy(new PercentDiscountPolicy(10)); + + // when + voucherRepository.update(voucher); + + // then + assertThat(voucher.getDiscountPolicy()).isInstanceOf(PercentDiscountPolicy.class); + assertThat(voucher.getDiscountPolicy().getAmount()).isEqualTo(10); + } + + @Test + @DisplayName("바우처를 삭제한다.") + void deleteById() { + // given + Voucher voucher = new Voucher(new FixedAmountDiscountPolicy(5000)); + + // when + voucherRepository.deleteById(voucher.getId()); + + // then + Optional result = voucherRepository.findById(voucher.getId()); + assertThat(result).isEmpty(); + } +} \ No newline at end of file From 6cb3d7b0e87f04eff3fa816f1d4b43896cf015db Mon Sep 17 00:00:00 2001 From: Yiseul Park Date: Fri, 7 Jul 2023 22:54:06 +0900 Subject: [PATCH 18/28] =?UTF-8?q?chore:=20=EB=A1=9C=EA=B7=B8=EB=B0=B1=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/logback.xml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index 168e7ebf0d..17d427ba1a 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -21,11 +21,7 @@ - - - - - + \ No newline at end of file From 396a89eac30484c8b09f120cc2e0fe6422dc2dae Mon Sep 17 00:00:00 2001 From: Yiseul Park Date: Sat, 8 Jul 2023 00:00:22 +0900 Subject: [PATCH 19/28] =?UTF-8?q?feat:=20=EA=B3=A0=EA=B0=9D=20CRUD=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../customer/domain/Customer.java | 31 ++++++ .../customer/domain/CustomerRepository.java | 18 ++++ .../customer/domain/CustomerType.java | 13 +++ .../JdbcTemplateCustomerRepository.java | 76 ++++++++++++++ src/main/resources/schema.sql | 8 ++ .../JdbcTemplateCustomerRepositoryTest.java | 99 +++++++++++++++++++ 6 files changed, 245 insertions(+) create mode 100644 src/main/java/com/programmers/vouchermanagement/customer/domain/Customer.java create mode 100644 src/main/java/com/programmers/vouchermanagement/customer/domain/CustomerRepository.java create mode 100644 src/main/java/com/programmers/vouchermanagement/customer/domain/CustomerType.java create mode 100644 src/main/java/com/programmers/vouchermanagement/customer/infrastructure/JdbcTemplateCustomerRepository.java create mode 100644 src/test/java/com/programmers/vouchermanagement/customer/infrastructure/JdbcTemplateCustomerRepositoryTest.java diff --git a/src/main/java/com/programmers/vouchermanagement/customer/domain/Customer.java b/src/main/java/com/programmers/vouchermanagement/customer/domain/Customer.java new file mode 100644 index 0000000000..2403093a14 --- /dev/null +++ b/src/main/java/com/programmers/vouchermanagement/customer/domain/Customer.java @@ -0,0 +1,31 @@ +package com.programmers.vouchermanagement.customer.domain; + +import lombok.EqualsAndHashCode; +import lombok.Getter; + +import java.util.UUID; + +@Getter +@EqualsAndHashCode +public class Customer { + + private final UUID id; + private final String name; + private CustomerType type; + + public Customer(String name, CustomerType type) { + this.id = UUID.randomUUID(); + this.name = name; + this.type = type; + } + + public Customer(UUID id, String name, CustomerType type) { + this.id = id; + this.name = name; + this.type = type; + } + + public void changeType(CustomerType type) { + this.type = type; + } +} diff --git a/src/main/java/com/programmers/vouchermanagement/customer/domain/CustomerRepository.java b/src/main/java/com/programmers/vouchermanagement/customer/domain/CustomerRepository.java new file mode 100644 index 0000000000..9e31b38435 --- /dev/null +++ b/src/main/java/com/programmers/vouchermanagement/customer/domain/CustomerRepository.java @@ -0,0 +1,18 @@ +package com.programmers.vouchermanagement.customer.domain; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +public interface CustomerRepository { + + Customer save(Customer customer); + + Optional findById(UUID id); + + List findAll(); + + void update(Customer customer); + + void deleteById(UUID id); +} diff --git a/src/main/java/com/programmers/vouchermanagement/customer/domain/CustomerType.java b/src/main/java/com/programmers/vouchermanagement/customer/domain/CustomerType.java new file mode 100644 index 0000000000..dbcb526cba --- /dev/null +++ b/src/main/java/com/programmers/vouchermanagement/customer/domain/CustomerType.java @@ -0,0 +1,13 @@ +package com.programmers.vouchermanagement.customer.domain; + +public enum CustomerType { + BLACK, WHITE; + + public static CustomerType from(String type) { + try { + return valueOf(type.toUpperCase()); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("고객 명단에 존재하지 않습니다."); + } + } +} diff --git a/src/main/java/com/programmers/vouchermanagement/customer/infrastructure/JdbcTemplateCustomerRepository.java b/src/main/java/com/programmers/vouchermanagement/customer/infrastructure/JdbcTemplateCustomerRepository.java new file mode 100644 index 0000000000..d61c59eb6f --- /dev/null +++ b/src/main/java/com/programmers/vouchermanagement/customer/infrastructure/JdbcTemplateCustomerRepository.java @@ -0,0 +1,76 @@ +package com.programmers.vouchermanagement.customer.infrastructure; + +import com.programmers.vouchermanagement.customer.domain.Customer; +import com.programmers.vouchermanagement.customer.domain.CustomerRepository; +import com.programmers.vouchermanagement.customer.domain.CustomerType; +import org.springframework.context.annotation.Primary; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Repository; + +import javax.sql.DataSource; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +@Primary +@Repository +public class JdbcTemplateCustomerRepository implements CustomerRepository { + + private final JdbcTemplate jdbcTemplate; + + public JdbcTemplateCustomerRepository(DataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + @Override + public Customer save(Customer customer) { + String sql = "insert into customer (id, name, type) values (?, ?, ?)"; + jdbcTemplate.update(sql, + customer.getId().toString(), + customer.getName(), + customer.getType().toString()); + return customer; + } + + @Override + public Optional findById(UUID id) { + String sql = "select * from customer where id = ?"; + try { + Customer customer = jdbcTemplate.queryForObject(sql, customerRowMapper(), id.toString()); + return Optional.of(customer); + } catch (EmptyResultDataAccessException e) { + return Optional.empty(); + } + } + + @Override + public List findAll() { + String sql = "select * from customer"; + return jdbcTemplate.query(sql, customerRowMapper()); + } + + @Override + public void update(Customer customer) { + String sql = "update customer set type = ? where id = ?"; + jdbcTemplate.update(sql, + customer.getType().toString(), + customer.getId().toString()); + } + + @Override + public void deleteById(UUID id) { + String sql = "delete from customer where id = ?"; + jdbcTemplate.update(sql, id.toString()); + } + + private RowMapper customerRowMapper() { + return (rs, rowNum) -> { + UUID id = UUID.fromString(rs.getString("id")); + String name = rs.getString("name"); + CustomerType type = CustomerType.valueOf(rs.getString("type")); + return new Customer(id, name, type); + }; + } +} diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index e23b485ecc..b9d031d28a 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -1,4 +1,5 @@ DROP TABLE IF EXISTS voucher; +DROP TABLE IF EXISTS customer; CREATE TABLE voucher ( id VARCHAR(36), @@ -6,3 +7,10 @@ CREATE TABLE voucher ( amount int NOT NULL, primary key (id) ); + +CREATE TABLE customer ( + id VARCHAR(36), + name VARCHAR(20) NOT NULL, + type VARCHAR(20) NOT NULL, + primary key (id) +); diff --git a/src/test/java/com/programmers/vouchermanagement/customer/infrastructure/JdbcTemplateCustomerRepositoryTest.java b/src/test/java/com/programmers/vouchermanagement/customer/infrastructure/JdbcTemplateCustomerRepositoryTest.java new file mode 100644 index 0000000000..b5b18dc941 --- /dev/null +++ b/src/test/java/com/programmers/vouchermanagement/customer/infrastructure/JdbcTemplateCustomerRepositoryTest.java @@ -0,0 +1,99 @@ +package com.programmers.vouchermanagement.customer.infrastructure; + +import com.programmers.vouchermanagement.customer.domain.Customer; +import com.programmers.vouchermanagement.customer.domain.CustomerRepository; +import com.programmers.vouchermanagement.customer.domain.CustomerType; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; + +@ActiveProfiles("test") +@SpringBootTest +@Transactional +class JdbcTemplateCustomerRepositoryTest { + + @Autowired + CustomerRepository customerRepository; + + @Test + @DisplayName("고객을 저장한다.") + void save() { + // given + Customer customer = new Customer("고객", CustomerType.WHITE); + + // when + customerRepository.save(customer); + + // then + Customer result = customerRepository.findById(customer.getId()).get(); + assertThat(result).isEqualTo(customer); + } + + @Test + @DisplayName("Id로 고객을 조회한다.") + void findById() { + // given + Customer customer = new Customer("고객", CustomerType.WHITE); + customerRepository.save(customer); + + // when + Customer result = customerRepository.findById(customer.getId()).get(); + + // then + assertThat(result).isEqualTo(customer); + } + + @Test + @DisplayName("고객을 모두 조회한다.") + void findAll() { + // given + Customer customer1 = new Customer("고객1", CustomerType.WHITE); + Customer customer2 = new Customer("고객2", CustomerType.BLACK); + + customerRepository.save(customer1); + customerRepository.save(customer2); + + // when + List result = customerRepository.findAll(); + + // then + assertThat(result).hasSize(2); + } + + @Test + @DisplayName("고객 정보를 업데이트한다.") + void update() { + // given + Customer customer = new Customer("고객", CustomerType.WHITE); + customerRepository.save(customer); + customer.changeType(CustomerType.BLACK); + + // when + customerRepository.update(customer); + + // then + assertThat(customer.getType()).isEqualTo(CustomerType.BLACK); + } + + @Test + @DisplayName("고객을 삭제한다.") + void deleteById() { + // given + Customer customer = new Customer("고객", CustomerType.WHITE); + + // when + customerRepository.deleteById(customer.getId()); + + // then + Optional result = customerRepository.findById(customer.getId()); + assertThat(result).isEmpty(); + } +} \ No newline at end of file From 7fe7487b3677f042bab1aac2bfe1c7644c0d0f2c Mon Sep 17 00:00:00 2001 From: Yiseul Park Date: Sat, 8 Jul 2023 17:09:20 +0900 Subject: [PATCH 20/28] =?UTF-8?q?test:=20=EA=B3=A0=EA=B0=9D=20=EC=9C=A0?= =?UTF-8?q?=ED=98=95=20=EB=B0=98=ED=99=98=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../customer/domain/CustomerType.java | 2 +- .../customer/domain/CustomerTypeTest.java | 55 +++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/programmers/vouchermanagement/customer/domain/CustomerTypeTest.java diff --git a/src/main/java/com/programmers/vouchermanagement/customer/domain/CustomerType.java b/src/main/java/com/programmers/vouchermanagement/customer/domain/CustomerType.java index dbcb526cba..32b4545421 100644 --- a/src/main/java/com/programmers/vouchermanagement/customer/domain/CustomerType.java +++ b/src/main/java/com/programmers/vouchermanagement/customer/domain/CustomerType.java @@ -7,7 +7,7 @@ public static CustomerType from(String type) { try { return valueOf(type.toUpperCase()); } catch (IllegalArgumentException e) { - throw new IllegalArgumentException("고객 명단에 존재하지 않습니다."); + throw new IllegalArgumentException("잘못된 고객 타입입니다."); } } } diff --git a/src/test/java/com/programmers/vouchermanagement/customer/domain/CustomerTypeTest.java b/src/test/java/com/programmers/vouchermanagement/customer/domain/CustomerTypeTest.java new file mode 100644 index 0000000000..0feca8e80a --- /dev/null +++ b/src/test/java/com/programmers/vouchermanagement/customer/domain/CustomerTypeTest.java @@ -0,0 +1,55 @@ +package com.programmers.vouchermanagement.customer.domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class CustomerTypeTest { + + @Nested + @DisplayName("고객 유형에 적합한 CustomerType 을 반환한다.") + class fromSuccess { + + @Test + @DisplayName("white 가 들어온 경우") + void whenWhiteComeInto() { + // given + String type = "white"; + + // when + CustomerType result = CustomerType.from(type); + + // then + assertThat(result).isEqualTo(CustomerType.WHITE); + } + + @Test + @DisplayName("black 가 들어온 경우") + void whenBlackComeInto() { + // given + String type = "black"; + + // when + CustomerType result = CustomerType.from(type); + + // then + assertThat(result).isEqualTo(CustomerType.BLACK); + } + } + + + @Test + @DisplayName("존재하지 않는 고객 유형이 들어오면 에외가 발생한다.") + void fromException() { + // given + String type = "red"; + + // given & then + assertThatThrownBy(() -> CustomerType.from(type)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("잘못된 고객 타입입니다."); + } +} \ No newline at end of file From 29ccf9386cff9fe32c3538c45e03b8073b3b3530 Mon Sep 17 00:00:00 2001 From: Yiseul Park Date: Sat, 8 Jul 2023 18:25:27 +0900 Subject: [PATCH 21/28] =?UTF-8?q?refactor:=20=EC=9E=85=EC=B6=9C=EB=A0=A5?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC,=20Command=20&=20DiscountType=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CommandLineController.java | 14 ++-- .../vouchermanagement/view/Command.java | 33 +++++----- .../vouchermanagement/view/Console.java | 64 ------------------- .../vouchermanagement/view/InputView.java | 38 +++++++++++ .../vouchermanagement/view/OutputView.java | 35 ++++++++++ .../voucher/domain/DiscountType.java | 25 ++++---- .../voucher/domain/DiscountTypeTest.java | 34 +++++----- 7 files changed, 128 insertions(+), 115 deletions(-) delete mode 100644 src/main/java/com/programmers/vouchermanagement/view/Console.java create mode 100644 src/main/java/com/programmers/vouchermanagement/view/InputView.java create mode 100644 src/main/java/com/programmers/vouchermanagement/view/OutputView.java diff --git a/src/main/java/com/programmers/vouchermanagement/CommandLineController.java b/src/main/java/com/programmers/vouchermanagement/CommandLineController.java index 2a2b63dbe0..b9f1fb9f41 100644 --- a/src/main/java/com/programmers/vouchermanagement/CommandLineController.java +++ b/src/main/java/com/programmers/vouchermanagement/CommandLineController.java @@ -1,7 +1,8 @@ package com.programmers.vouchermanagement; import com.programmers.vouchermanagement.view.Command; -import com.programmers.vouchermanagement.view.Console; +import com.programmers.vouchermanagement.view.InputView; +import com.programmers.vouchermanagement.view.OutputView; import com.programmers.vouchermanagement.voucher.domain.DiscountType; import com.programmers.vouchermanagement.voucher.application.VoucherDto; import com.programmers.vouchermanagement.voucher.presentation.VoucherController; @@ -29,7 +30,6 @@ public void run(String... args) { try { running = isRunning(); } catch (RuntimeException e) { - Console.outputErrorMessage(e.getMessage()); log.error(e.getMessage()); } @@ -37,17 +37,19 @@ public void run(String... args) { } private boolean isRunning() { - Command command = Command.from(Console.selectCommand()); + OutputView.showCommand(); + Command command = InputView.inputCommand(); switch (command) { case CREATE -> { - DiscountType discountType = DiscountType.from(Console.selectDiscountType()); - int discountAmount = Console.inputDiscountAmount(); + OutputView.showDiscountType(); + DiscountType discountType = InputView.inputDiscountType(); + int discountAmount = InputView.inputDiscountAmount(); VoucherDto request = new VoucherDto(discountType, discountAmount); voucherController.createVoucher(request); } case LIST-> { List vouchers = voucherController.getVouchers(); - Console.outputVouchers(vouchers); + OutputView.showVouchers(vouchers); } case EXIT -> { return false; diff --git a/src/main/java/com/programmers/vouchermanagement/view/Command.java b/src/main/java/com/programmers/vouchermanagement/view/Command.java index 6d80749e53..07b31c9b91 100644 --- a/src/main/java/com/programmers/vouchermanagement/view/Command.java +++ b/src/main/java/com/programmers/vouchermanagement/view/Command.java @@ -1,37 +1,40 @@ package com.programmers.vouchermanagement.view; +import lombok.Getter; + import java.util.Collections; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; +@Getter public enum Command { - CREATE("create"), - LIST("list"), - EXIT("exit"); + EXIT("1", "프로그램 종료"), + CREATE("2", "바우처 생성"), + LIST("3", "바우처 조회"), + DELETE("4", "바우처 삭제"), + UPDATE("5", "바우처 수정"); - private final String name; + private final String number; + private final String description; private static final Map COMMAND_MAP; static { COMMAND_MAP = Collections.unmodifiableMap(Stream.of(values()) - .collect(Collectors.toMap(Command::getName, Function.identity()))); - } - - Command(String name) { - this.name = name; + .collect(Collectors.toMap(Command::getNumber, Function.identity()))); } - public String getName() { - return name; + Command(String number, String description) { + this.number = number; + this.description = description; } - public static Command from(String name) { - if (COMMAND_MAP.containsKey(name)) { - return COMMAND_MAP.get(name); + public static Command from(String number) { + if (COMMAND_MAP.containsKey(number)) { + return COMMAND_MAP.get(number); } - throw new IllegalArgumentException("This command does not exist."); + throw new IllegalArgumentException("존재하지 않는 명령어 입니다."); } } diff --git a/src/main/java/com/programmers/vouchermanagement/view/Console.java b/src/main/java/com/programmers/vouchermanagement/view/Console.java deleted file mode 100644 index e93b5c11b4..0000000000 --- a/src/main/java/com/programmers/vouchermanagement/view/Console.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.programmers.vouchermanagement.view; - -import com.programmers.vouchermanagement.voucher.application.VoucherDto; - -import java.util.List; -import java.util.Scanner; - -public class Console { - - private final static Scanner SCANNER = new Scanner(System.in); - - private static String inputString() { - return SCANNER.nextLine(); - } - - public static String selectCommand() { - System.out.println(""" - - === Voucher Program === - Type exit to exit the program. - Type create to create a new voucher. - Type list to list all vouchers. - """); - return inputString(); - } - - public static String selectDiscountType() { - System.out.println(""" - - Choose a discount type. - Type fix to select a fixed discount - Type percent to select a fixed discount - """); - return inputString(); - } - - public static int inputDiscountAmount() { - System.out.println("\nPlease enter the discount amount\n"); - return inputInt(); - } - - private static int inputInt() { - int inputValue = 0; - try { - inputValue = Integer.parseInt(inputString()); - } catch (NumberFormatException e) { - throw new IllegalArgumentException("Please enter only numbers."); - } - return inputValue; - } - - public static void outputVouchers(List vouchers) { - System.out.println("\nThis is a list of vouchers"); - StringBuilder builder = new StringBuilder(); - vouchers.stream() - .map(voucher -> "Voucher Type: " + voucher.discountType().getName() + ", Amount: " + voucher.amount()) - .forEach(builder::append); - System.out.println(builder); - } - - public static void outputErrorMessage(String errorMessage) { - System.out.println(errorMessage); - } -} diff --git a/src/main/java/com/programmers/vouchermanagement/view/InputView.java b/src/main/java/com/programmers/vouchermanagement/view/InputView.java new file mode 100644 index 0000000000..31a2b73b28 --- /dev/null +++ b/src/main/java/com/programmers/vouchermanagement/view/InputView.java @@ -0,0 +1,38 @@ +package com.programmers.vouchermanagement.view; + +import com.programmers.vouchermanagement.voucher.domain.DiscountType; + +import java.util.Scanner; + +public class InputView { + + private static final String INPUT_COMMAND = "명령어 번호를 입력해주세요."; + private static final String INPUT_DISCOUNT_TYPE = "할인 유형 번호를 입력해주세요."; + private static final String INPUT_DISCOUNT_AMOUNT = "할인 양을 입력해주세요."; + private static final Scanner SCANNER = new Scanner(System.in); + + public static Command inputCommand() { + System.out.println(INPUT_COMMAND); + return Command.from(SCANNER.nextLine()); + } + + public static DiscountType inputDiscountType() { + System.out.println(INPUT_DISCOUNT_TYPE); + return DiscountType.from(SCANNER.nextLine()); + } + + public static int inputDiscountAmount() { + System.out.println(INPUT_DISCOUNT_AMOUNT); + return inputAmount(); + } + + private static int inputAmount() { + int inputValue = 0; + try { + inputValue = Integer.parseInt(SCANNER.nextLine()); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("숫자만 입력해주세요"); + } + return inputValue; + } +} diff --git a/src/main/java/com/programmers/vouchermanagement/view/OutputView.java b/src/main/java/com/programmers/vouchermanagement/view/OutputView.java new file mode 100644 index 0000000000..7e494bc158 --- /dev/null +++ b/src/main/java/com/programmers/vouchermanagement/view/OutputView.java @@ -0,0 +1,35 @@ +package com.programmers.vouchermanagement.view; + +import com.programmers.vouchermanagement.voucher.application.VoucherDto; +import com.programmers.vouchermanagement.voucher.domain.DiscountType; + +import java.text.MessageFormat; +import java.util.List; + +public class OutputView { + + private static final String VOUCHER_PROGRAM = "============= Voucher Program ============="; + private static final String DISCOUNT_TYPE = "=============== 바우처 할인 유형 ==============="; + private static final String VOUCHER_LIST = "================= 바우처 조회 ================="; + + public static void showCommand() { + System.out.println(VOUCHER_PROGRAM); + for (Command command : Command.values()) { + System.out.println(MessageFormat.format("({0}) {1} : {2}", command.getNumber(), command, command.getDescription())); + } + } + + public static void showDiscountType() { + System.out.println(DISCOUNT_TYPE); + for (DiscountType discountType : DiscountType.values()) { + System.out.println(MessageFormat.format("({0}) {1} : {2}", discountType.getNumber(), discountType, discountType.getName())); + } + } + + public static void showVouchers(List vouchers) { + System.out.println(VOUCHER_LIST); + for (VoucherDto voucher : vouchers) { + System.out.println(MessageFormat.format("{0} : {1}", voucher.discountType().getName(), voucher.amount())); + } + } +} diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountType.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountType.java index 9701a15fe2..dd79f5be28 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountType.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountType.java @@ -1,39 +1,40 @@ package com.programmers.vouchermanagement.voucher.domain; +import lombok.Getter; + import java.util.Collections; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; +@Getter public enum DiscountType { - FIX("fix", FixedAmountDiscountPolicy::new), - PERCENT("percent", PercentDiscountPolicy::new); + FIX("1", "정액 할인", FixedAmountDiscountPolicy::new), + PERCENT("2", "정률 할인", PercentDiscountPolicy::new); + private final String number; private final String name; private final Function voucherCreationFunction; private static final Map DISCOUNT_TYPE_MAP; static { DISCOUNT_TYPE_MAP = Collections.unmodifiableMap(Stream.of(values()) - .collect(Collectors.toMap(DiscountType::getName, Function.identity()))); + .collect(Collectors.toMap(DiscountType::getNumber, Function.identity()))); } - DiscountType(String name, Function voucherCreationFunction) { + DiscountType(String number, String name, Function voucherCreationFunction) { + this.number = number; this.name = name; this.voucherCreationFunction = voucherCreationFunction; } - public String getName() { - return name; - } - - public static DiscountType from(String name) { - if (DISCOUNT_TYPE_MAP.containsKey(name)) { - return DISCOUNT_TYPE_MAP.get(name); + public static DiscountType from(String number) { + if (DISCOUNT_TYPE_MAP.containsKey(number)) { + return DISCOUNT_TYPE_MAP.get(number); } - throw new IllegalArgumentException("This discount type does not exist."); + throw new IllegalArgumentException("존재하지 않는 할인 유형 입니다."); } public DiscountPolicy createDiscountPolicy(int amount) { diff --git a/src/test/java/com/programmers/vouchermanagement/voucher/domain/DiscountTypeTest.java b/src/test/java/com/programmers/vouchermanagement/voucher/domain/DiscountTypeTest.java index eed5af001a..4603db3bd6 100644 --- a/src/test/java/com/programmers/vouchermanagement/voucher/domain/DiscountTypeTest.java +++ b/src/test/java/com/programmers/vouchermanagement/voucher/domain/DiscountTypeTest.java @@ -11,16 +11,16 @@ class DiscountTypeTest { @Nested @DisplayName("할인 유형에 적합한 DiscountType 을 반환한다.") - class returnAppropriateDiscountType { + class from_success { @Test @DisplayName("fix 가 들어온 경우") void WhenFixComeInto() { - // when - String name = "fix"; - // given - DiscountType result = DiscountType.from(name); + String number = "1"; // Fix amount + + // when + DiscountType result = DiscountType.from(number); // then assertThat(result).isEqualTo(DiscountType.FIX); @@ -29,11 +29,11 @@ void WhenFixComeInto() { @Test @DisplayName("percent 가 들어온 경우") void WhenPercentComeInto() { - // when - String name = "percent"; - // given - DiscountType result = DiscountType.from(name); + String number = "2"; // Percent + + // when + DiscountType result = DiscountType.from(number); // then assertThat(result).isEqualTo(DiscountType.PERCENT); @@ -42,15 +42,13 @@ void WhenPercentComeInto() { @Test @DisplayName("존재하지 않는 할인 유형이 들어오면 에외가 발생한다.") - void occurExceptionWhenDiscountTypeDoesNotExist() { - // when - String name = "fixx"; - - // given & then - assertThatThrownBy(() -> { - DiscountType.from(name); - }) + void from_exception() { + // given + String number = "3"; + + // when & then + assertThatThrownBy(() -> DiscountType.from(number)) .isInstanceOf(IllegalArgumentException.class) - .hasMessage("This discount type does not exist."); + .hasMessage("존재하지 않는 할인 유형 입니다."); } } \ No newline at end of file From e065798738f115d46b580b788d32dbf2b760c6ef Mon Sep 17 00:00:00 2001 From: Yiseul Park Date: Sat, 8 Jul 2023 19:52:16 +0900 Subject: [PATCH 22/28] =?UTF-8?q?refactor:=20=EB=B0=94=EC=9A=B0=EC=B2=98?= =?UTF-8?q?=20DTO=20=EC=9A=94=EC=B2=AD,=20=EC=9D=91=EB=8B=B5=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC,=20=EB=B0=94=EC=9A=B0=EC=B2=98=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=20=ED=8F=AC=EB=A7=B7=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CommandLineController.java | 9 ++++---- .../vouchermanagement/view/OutputView.java | 20 ++++++++++++++---- .../voucher/application/VoucherDto.java | 13 ------------ .../voucher/application/VoucherService.java | 14 +++++++------ .../dto/request/VoucherCreationRequest.java | 6 ++++++ .../voucher/dto/response/VoucherResponse.java | 21 +++++++++++++++++++ .../presentation/VoucherController.java | 7 ++++--- .../application/VoucherServiceTest.java | 8 ++++--- 8 files changed, 65 insertions(+), 33 deletions(-) delete mode 100644 src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherDto.java create mode 100644 src/main/java/com/programmers/vouchermanagement/voucher/dto/request/VoucherCreationRequest.java create mode 100644 src/main/java/com/programmers/vouchermanagement/voucher/dto/response/VoucherResponse.java diff --git a/src/main/java/com/programmers/vouchermanagement/CommandLineController.java b/src/main/java/com/programmers/vouchermanagement/CommandLineController.java index b9f1fb9f41..1e601975a5 100644 --- a/src/main/java/com/programmers/vouchermanagement/CommandLineController.java +++ b/src/main/java/com/programmers/vouchermanagement/CommandLineController.java @@ -4,7 +4,8 @@ import com.programmers.vouchermanagement.view.InputView; import com.programmers.vouchermanagement.view.OutputView; import com.programmers.vouchermanagement.voucher.domain.DiscountType; -import com.programmers.vouchermanagement.voucher.application.VoucherDto; +import com.programmers.vouchermanagement.voucher.dto.request.VoucherCreationRequest; +import com.programmers.vouchermanagement.voucher.dto.response.VoucherResponse; import com.programmers.vouchermanagement.voucher.presentation.VoucherController; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -44,11 +45,11 @@ private boolean isRunning() { OutputView.showDiscountType(); DiscountType discountType = InputView.inputDiscountType(); int discountAmount = InputView.inputDiscountAmount(); - VoucherDto request = new VoucherDto(discountType, discountAmount); - voucherController.createVoucher(request); + VoucherCreationRequest voucherCreationRequest = new VoucherCreationRequest(discountType, discountAmount); + voucherController.createVoucher(voucherCreationRequest); } case LIST-> { - List vouchers = voucherController.getVouchers(); + List vouchers = voucherController.getVouchers(); OutputView.showVouchers(vouchers); } case EXIT -> { diff --git a/src/main/java/com/programmers/vouchermanagement/view/OutputView.java b/src/main/java/com/programmers/vouchermanagement/view/OutputView.java index 7e494bc158..011784423b 100644 --- a/src/main/java/com/programmers/vouchermanagement/view/OutputView.java +++ b/src/main/java/com/programmers/vouchermanagement/view/OutputView.java @@ -1,7 +1,7 @@ package com.programmers.vouchermanagement.view; -import com.programmers.vouchermanagement.voucher.application.VoucherDto; import com.programmers.vouchermanagement.voucher.domain.DiscountType; +import com.programmers.vouchermanagement.voucher.dto.response.VoucherResponse; import java.text.MessageFormat; import java.util.List; @@ -11,6 +11,8 @@ public class OutputView { private static final String VOUCHER_PROGRAM = "============= Voucher Program ============="; private static final String DISCOUNT_TYPE = "=============== 바우처 할인 유형 ==============="; private static final String VOUCHER_LIST = "================= 바우처 조회 ================="; + private static final String LINE = "ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ"; + private static final String VOUCHER_TABLE_TITLE = " 번호 | 바우처 ID | 할인 유형 | 할인 양 "; public static void showCommand() { System.out.println(VOUCHER_PROGRAM); @@ -26,10 +28,20 @@ public static void showDiscountType() { } } - public static void showVouchers(List vouchers) { + public static void showVouchers(List vouchers) { System.out.println(VOUCHER_LIST); - for (VoucherDto voucher : vouchers) { - System.out.println(MessageFormat.format("{0} : {1}", voucher.discountType().getName(), voucher.amount())); + showVoucher(vouchers); + } + + private static void showVoucher(List vouchers) { + System.out.println(LINE); + System.out.println(VOUCHER_TABLE_TITLE); + System.out.println(LINE); + int i = 1; + for (VoucherResponse voucher : vouchers) { + System.out.println(MessageFormat.format(" {0} | {1} | {2} | {3}", i, voucher.getId(), voucher.getType().getName(), voucher.getAmount())); + System.out.println(LINE); + i++; } } } diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherDto.java b/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherDto.java deleted file mode 100644 index 754004b8b2..0000000000 --- a/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherDto.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.programmers.vouchermanagement.voucher.application; - -import com.programmers.vouchermanagement.voucher.domain.DiscountPolicy; -import com.programmers.vouchermanagement.voucher.domain.DiscountType; -import com.programmers.vouchermanagement.voucher.domain.Voucher; - -public record VoucherDto(DiscountType discountType, int amount) { - - public static VoucherDto toDto(Voucher voucher) { - DiscountPolicy discountPolicy = voucher.getDiscountPolicy(); - return new VoucherDto(discountPolicy.getType(), discountPolicy.getAmount()); - } -} diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherService.java b/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherService.java index 9dc0ad1e9f..24be29ce39 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherService.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherService.java @@ -4,11 +4,14 @@ import com.programmers.vouchermanagement.voucher.domain.DiscountType; import com.programmers.vouchermanagement.voucher.domain.Voucher; import com.programmers.vouchermanagement.voucher.domain.VoucherRepository; +import com.programmers.vouchermanagement.voucher.dto.request.VoucherCreationRequest; +import com.programmers.vouchermanagement.voucher.dto.response.VoucherResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.util.List; +import java.util.stream.Collectors; @Slf4j @Service @@ -17,19 +20,18 @@ public class VoucherService { private final VoucherRepository voucherRepository; - public Voucher createVoucher(VoucherDto request) { - DiscountType discountType = request.discountType(); + public Voucher createVoucher(VoucherCreationRequest request) { + DiscountType discountType = request.type(); int amount = request.amount(); DiscountPolicy discountPolicy = discountType.createDiscountPolicy(amount); Voucher voucher = new Voucher(discountPolicy); - log.info("Create Voucher! DiscountType: {}, DiscountAmount: {}", voucher.getClass().getSimpleName(), request.amount()); return voucherRepository.save(voucher); } - public List getVouchers() { + public List getVouchers() { List vouchers = voucherRepository.findAll(); return vouchers.stream() - .map(VoucherDto::toDto) - .toList(); + .map(VoucherResponse::new) + .collect(Collectors.toList()); } } diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/dto/request/VoucherCreationRequest.java b/src/main/java/com/programmers/vouchermanagement/voucher/dto/request/VoucherCreationRequest.java new file mode 100644 index 0000000000..e5c8f4cdab --- /dev/null +++ b/src/main/java/com/programmers/vouchermanagement/voucher/dto/request/VoucherCreationRequest.java @@ -0,0 +1,6 @@ +package com.programmers.vouchermanagement.voucher.dto.request; + +import com.programmers.vouchermanagement.voucher.domain.DiscountType; + +public record VoucherCreationRequest(DiscountType type, int amount) { +} \ No newline at end of file diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/dto/response/VoucherResponse.java b/src/main/java/com/programmers/vouchermanagement/voucher/dto/response/VoucherResponse.java new file mode 100644 index 0000000000..7f327d7484 --- /dev/null +++ b/src/main/java/com/programmers/vouchermanagement/voucher/dto/response/VoucherResponse.java @@ -0,0 +1,21 @@ +package com.programmers.vouchermanagement.voucher.dto.response; + +import com.programmers.vouchermanagement.voucher.domain.DiscountType; +import com.programmers.vouchermanagement.voucher.domain.Voucher; +import lombok.Getter; + +import java.util.UUID; + +@Getter +public class VoucherResponse { + + private final UUID id; + private final DiscountType type; + private final int amount; + + public VoucherResponse(Voucher voucher) { + this.id = voucher.getId(); + this.type = voucher.getDiscountPolicy().getType(); + this.amount = voucher.getDiscountPolicy().getAmount(); + } +} diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/presentation/VoucherController.java b/src/main/java/com/programmers/vouchermanagement/voucher/presentation/VoucherController.java index 438005260b..c7a7a1a7a4 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/presentation/VoucherController.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/presentation/VoucherController.java @@ -1,7 +1,8 @@ package com.programmers.vouchermanagement.voucher.presentation; import com.programmers.vouchermanagement.voucher.application.VoucherService; -import com.programmers.vouchermanagement.voucher.application.VoucherDto; +import com.programmers.vouchermanagement.voucher.dto.request.VoucherCreationRequest; +import com.programmers.vouchermanagement.voucher.dto.response.VoucherResponse; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Controller; @@ -13,11 +14,11 @@ public class VoucherController { private final VoucherService voucherService; - public void createVoucher(VoucherDto request) { + public void createVoucher(VoucherCreationRequest request) { voucherService.createVoucher(request); } - public List getVouchers() { + public List getVouchers() { return voucherService.getVouchers(); } } diff --git a/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherServiceTest.java b/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherServiceTest.java index 07e96ea642..85e7c648c6 100644 --- a/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherServiceTest.java +++ b/src/test/java/com/programmers/vouchermanagement/voucher/application/VoucherServiceTest.java @@ -1,6 +1,8 @@ package com.programmers.vouchermanagement.voucher.application; import com.programmers.vouchermanagement.voucher.domain.*; +import com.programmers.vouchermanagement.voucher.dto.request.VoucherCreationRequest; +import com.programmers.vouchermanagement.voucher.dto.response.VoucherResponse; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -29,8 +31,8 @@ class VoucherServiceTest { @DisplayName("바우처를 생성한다.") void createVoucher() { // given - VoucherDto request = new VoucherDto(DiscountType.FIX, 5000); - DiscountType discountType = request.discountType(); + VoucherCreationRequest request = new VoucherCreationRequest(DiscountType.FIX, 5000); + DiscountType discountType = request.type(); int amount = request.amount(); DiscountPolicy discountPolicy = discountType.createDiscountPolicy(amount); Voucher voucher = new Voucher(discountPolicy); @@ -59,7 +61,7 @@ void getVouchers() { .willReturn(List.of(voucher1, voucher2)); // when - List result = voucherService.getVouchers(); + List result = voucherService.getVouchers(); // then assertThat(result).hasSize(2); From 0f58e7419faf69d278971fd6b6c6960fc5ee5b7c Mon Sep 17 00:00:00 2001 From: Yiseul Park Date: Sat, 8 Jul 2023 20:10:35 +0900 Subject: [PATCH 23/28] =?UTF-8?q?refactor:=20=EB=B0=94=EC=9A=B0=EC=B2=98?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1=20=EC=8B=9C=20=EC=A0=95=EB=B3=B4=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=20=EB=A9=94=EC=86=8C=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vouchermanagement/CommandLineController.java | 7 ++----- .../com/programmers/vouchermanagement/view/InputView.java | 7 +++++++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/programmers/vouchermanagement/CommandLineController.java b/src/main/java/com/programmers/vouchermanagement/CommandLineController.java index 1e601975a5..d623c28027 100644 --- a/src/main/java/com/programmers/vouchermanagement/CommandLineController.java +++ b/src/main/java/com/programmers/vouchermanagement/CommandLineController.java @@ -3,7 +3,6 @@ import com.programmers.vouchermanagement.view.Command; import com.programmers.vouchermanagement.view.InputView; import com.programmers.vouchermanagement.view.OutputView; -import com.programmers.vouchermanagement.voucher.domain.DiscountType; import com.programmers.vouchermanagement.voucher.dto.request.VoucherCreationRequest; import com.programmers.vouchermanagement.voucher.dto.response.VoucherResponse; import com.programmers.vouchermanagement.voucher.presentation.VoucherController; @@ -43,10 +42,8 @@ private boolean isRunning() { switch (command) { case CREATE -> { OutputView.showDiscountType(); - DiscountType discountType = InputView.inputDiscountType(); - int discountAmount = InputView.inputDiscountAmount(); - VoucherCreationRequest voucherCreationRequest = new VoucherCreationRequest(discountType, discountAmount); - voucherController.createVoucher(voucherCreationRequest); + VoucherCreationRequest request = InputView.inputVoucherInfo(); + voucherController.createVoucher(request); } case LIST-> { List vouchers = voucherController.getVouchers(); diff --git a/src/main/java/com/programmers/vouchermanagement/view/InputView.java b/src/main/java/com/programmers/vouchermanagement/view/InputView.java index 31a2b73b28..1c7e611daa 100644 --- a/src/main/java/com/programmers/vouchermanagement/view/InputView.java +++ b/src/main/java/com/programmers/vouchermanagement/view/InputView.java @@ -1,6 +1,7 @@ package com.programmers.vouchermanagement.view; import com.programmers.vouchermanagement.voucher.domain.DiscountType; +import com.programmers.vouchermanagement.voucher.dto.request.VoucherCreationRequest; import java.util.Scanner; @@ -16,6 +17,12 @@ public static Command inputCommand() { return Command.from(SCANNER.nextLine()); } + public static VoucherCreationRequest inputVoucherInfo() { + DiscountType type = inputDiscountType(); + int amount = inputDiscountAmount(); + return new VoucherCreationRequest(type, amount); + } + public static DiscountType inputDiscountType() { System.out.println(INPUT_DISCOUNT_TYPE); return DiscountType.from(SCANNER.nextLine()); From cdde2c8cfbb2e703395d37e17904cd0e4f06b6d3 Mon Sep 17 00:00:00 2001 From: Yiseul Park Date: Sat, 8 Jul 2023 20:26:58 +0900 Subject: [PATCH 24/28] =?UTF-8?q?feat:=20=EC=BD=98=EC=86=94=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EB=B0=94=EC=9A=B0=EC=B2=98=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vouchermanagement/CommandLineController.java | 11 +++++++++++ .../programmers/vouchermanagement/view/Command.java | 4 ++-- .../programmers/vouchermanagement/view/InputView.java | 11 +++++++++++ .../vouchermanagement/view/OutputView.java | 6 ++++++ .../voucher/application/VoucherService.java | 11 +++++++++++ .../voucher/dto/request/VoucherUpdateRequest.java | 8 ++++++++ .../voucher/presentation/VoucherController.java | 5 +++++ 7 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/programmers/vouchermanagement/voucher/dto/request/VoucherUpdateRequest.java diff --git a/src/main/java/com/programmers/vouchermanagement/CommandLineController.java b/src/main/java/com/programmers/vouchermanagement/CommandLineController.java index d623c28027..8d155d92c1 100644 --- a/src/main/java/com/programmers/vouchermanagement/CommandLineController.java +++ b/src/main/java/com/programmers/vouchermanagement/CommandLineController.java @@ -4,6 +4,7 @@ import com.programmers.vouchermanagement.view.InputView; import com.programmers.vouchermanagement.view.OutputView; import com.programmers.vouchermanagement.voucher.dto.request.VoucherCreationRequest; +import com.programmers.vouchermanagement.voucher.dto.request.VoucherUpdateRequest; import com.programmers.vouchermanagement.voucher.dto.response.VoucherResponse; import com.programmers.vouchermanagement.voucher.presentation.VoucherController; import lombok.RequiredArgsConstructor; @@ -13,6 +14,7 @@ import org.springframework.stereotype.Controller; import java.util.List; +import java.util.UUID; @Profile("!test") @Slf4j @@ -52,6 +54,15 @@ private boolean isRunning() { case EXIT -> { return false; } + case UPDATE -> { + List vouchers = voucherController.getVouchers(); + OutputView.showVoucherUpdate(vouchers); + UUID id = InputView.inputUpdateVoucherId(vouchers); + OutputView.showDiscountType(); + VoucherCreationRequest updateVoucherInfo = InputView.inputVoucherInfo(); + VoucherUpdateRequest request = new VoucherUpdateRequest(id, updateVoucherInfo.type(), updateVoucherInfo.amount()); + voucherController.updateVoucher(request); + } } return true; } diff --git a/src/main/java/com/programmers/vouchermanagement/view/Command.java b/src/main/java/com/programmers/vouchermanagement/view/Command.java index 07b31c9b91..4290ba5cb7 100644 --- a/src/main/java/com/programmers/vouchermanagement/view/Command.java +++ b/src/main/java/com/programmers/vouchermanagement/view/Command.java @@ -14,8 +14,8 @@ public enum Command { EXIT("1", "프로그램 종료"), CREATE("2", "바우처 생성"), LIST("3", "바우처 조회"), - DELETE("4", "바우처 삭제"), - UPDATE("5", "바우처 수정"); + UPDATE("4", "바우처 수정"), + DELETE("5", "바우처 삭제"); private final String number; private final String description; diff --git a/src/main/java/com/programmers/vouchermanagement/view/InputView.java b/src/main/java/com/programmers/vouchermanagement/view/InputView.java index 1c7e611daa..20455de53a 100644 --- a/src/main/java/com/programmers/vouchermanagement/view/InputView.java +++ b/src/main/java/com/programmers/vouchermanagement/view/InputView.java @@ -2,14 +2,18 @@ import com.programmers.vouchermanagement.voucher.domain.DiscountType; import com.programmers.vouchermanagement.voucher.dto.request.VoucherCreationRequest; +import com.programmers.vouchermanagement.voucher.dto.response.VoucherResponse; +import java.util.List; import java.util.Scanner; +import java.util.UUID; public class InputView { private static final String INPUT_COMMAND = "명령어 번호를 입력해주세요."; private static final String INPUT_DISCOUNT_TYPE = "할인 유형 번호를 입력해주세요."; private static final String INPUT_DISCOUNT_AMOUNT = "할인 양을 입력해주세요."; + private static final String INPUT_VOUCHER_UPDATE = "수정할 바우처 번호를 입력해주세요."; private static final Scanner SCANNER = new Scanner(System.in); public static Command inputCommand() { @@ -42,4 +46,11 @@ private static int inputAmount() { } return inputValue; } + + public static UUID inputUpdateVoucherId(List vouchers) { + System.out.println(INPUT_VOUCHER_UPDATE); + String selectedVoucherNumber = SCANNER.nextLine(); + VoucherResponse voucherResponse = vouchers.get(Integer.parseInt(selectedVoucherNumber) - 1); + return voucherResponse.getId(); + } } diff --git a/src/main/java/com/programmers/vouchermanagement/view/OutputView.java b/src/main/java/com/programmers/vouchermanagement/view/OutputView.java index 011784423b..c7959d1e5b 100644 --- a/src/main/java/com/programmers/vouchermanagement/view/OutputView.java +++ b/src/main/java/com/programmers/vouchermanagement/view/OutputView.java @@ -13,6 +13,7 @@ public class OutputView { private static final String VOUCHER_LIST = "================= 바우처 조회 ================="; private static final String LINE = "ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ"; private static final String VOUCHER_TABLE_TITLE = " 번호 | 바우처 ID | 할인 유형 | 할인 양 "; + private static final String VOUCHER_UPDATE = "================= 바우처 수정 ================="; public static void showCommand() { System.out.println(VOUCHER_PROGRAM); @@ -44,4 +45,9 @@ private static void showVoucher(List vouchers) { i++; } } + + public static void showVoucherUpdate(List vouchers) { + System.out.println(VOUCHER_UPDATE); + showVoucher(vouchers); + } } diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherService.java b/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherService.java index 24be29ce39..f37ec509b2 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherService.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherService.java @@ -5,12 +5,14 @@ import com.programmers.vouchermanagement.voucher.domain.Voucher; import com.programmers.vouchermanagement.voucher.domain.VoucherRepository; import com.programmers.vouchermanagement.voucher.dto.request.VoucherCreationRequest; +import com.programmers.vouchermanagement.voucher.dto.request.VoucherUpdateRequest; import com.programmers.vouchermanagement.voucher.dto.response.VoucherResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.util.List; +import java.util.UUID; import java.util.stream.Collectors; @Slf4j @@ -34,4 +36,13 @@ public List getVouchers() { .map(VoucherResponse::new) .collect(Collectors.toList()); } + + public void updateVoucher(VoucherUpdateRequest request) { + UUID id = request.id(); + DiscountType discountType = request.type(); + int amount = request.amount(); + DiscountPolicy discountPolicy = discountType.createDiscountPolicy(amount); + Voucher voucher = new Voucher(id, discountPolicy); + voucherRepository.update(voucher); + } } diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/dto/request/VoucherUpdateRequest.java b/src/main/java/com/programmers/vouchermanagement/voucher/dto/request/VoucherUpdateRequest.java new file mode 100644 index 0000000000..51ccd551a9 --- /dev/null +++ b/src/main/java/com/programmers/vouchermanagement/voucher/dto/request/VoucherUpdateRequest.java @@ -0,0 +1,8 @@ +package com.programmers.vouchermanagement.voucher.dto.request; + +import com.programmers.vouchermanagement.voucher.domain.DiscountType; + +import java.util.UUID; + +public record VoucherUpdateRequest(UUID id, DiscountType type, int amount) { +} diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/presentation/VoucherController.java b/src/main/java/com/programmers/vouchermanagement/voucher/presentation/VoucherController.java index c7a7a1a7a4..da59781133 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/presentation/VoucherController.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/presentation/VoucherController.java @@ -2,6 +2,7 @@ import com.programmers.vouchermanagement.voucher.application.VoucherService; import com.programmers.vouchermanagement.voucher.dto.request.VoucherCreationRequest; +import com.programmers.vouchermanagement.voucher.dto.request.VoucherUpdateRequest; import com.programmers.vouchermanagement.voucher.dto.response.VoucherResponse; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Controller; @@ -21,4 +22,8 @@ public void createVoucher(VoucherCreationRequest request) { public List getVouchers() { return voucherService.getVouchers(); } + + public void updateVoucher(VoucherUpdateRequest request) { + voucherService.updateVoucher(request); + } } From de8fb3f001a7db84799fc5546fffb5ab5783153f Mon Sep 17 00:00:00 2001 From: Yiseul Park Date: Sat, 8 Jul 2023 20:37:47 +0900 Subject: [PATCH 25/28] =?UTF-8?q?feat:=20=EC=BD=98=EC=86=94=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EB=B0=94=EC=9A=B0=EC=B2=98=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vouchermanagement/CommandLineController.java | 8 +++++++- .../vouchermanagement/view/InputView.java | 12 +++++++++++- .../vouchermanagement/view/OutputView.java | 6 ++++++ .../voucher/application/VoucherService.java | 4 ++++ .../voucher/presentation/VoucherController.java | 5 +++++ 5 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/programmers/vouchermanagement/CommandLineController.java b/src/main/java/com/programmers/vouchermanagement/CommandLineController.java index 8d155d92c1..1d1ba3744f 100644 --- a/src/main/java/com/programmers/vouchermanagement/CommandLineController.java +++ b/src/main/java/com/programmers/vouchermanagement/CommandLineController.java @@ -57,12 +57,18 @@ private boolean isRunning() { case UPDATE -> { List vouchers = voucherController.getVouchers(); OutputView.showVoucherUpdate(vouchers); - UUID id = InputView.inputUpdateVoucherId(vouchers); + UUID id = InputView.inputVoucherUpdate(vouchers); OutputView.showDiscountType(); VoucherCreationRequest updateVoucherInfo = InputView.inputVoucherInfo(); VoucherUpdateRequest request = new VoucherUpdateRequest(id, updateVoucherInfo.type(), updateVoucherInfo.amount()); voucherController.updateVoucher(request); } + case DELETE -> { + List vouchers = voucherController.getVouchers(); + OutputView.showVoucherDelete(vouchers); + UUID id = InputView.inputVoucherDelete(vouchers); + voucherController.deleteVoucher(id); + } } return true; } diff --git a/src/main/java/com/programmers/vouchermanagement/view/InputView.java b/src/main/java/com/programmers/vouchermanagement/view/InputView.java index 20455de53a..26dcb44753 100644 --- a/src/main/java/com/programmers/vouchermanagement/view/InputView.java +++ b/src/main/java/com/programmers/vouchermanagement/view/InputView.java @@ -14,6 +14,7 @@ public class InputView { private static final String INPUT_DISCOUNT_TYPE = "할인 유형 번호를 입력해주세요."; private static final String INPUT_DISCOUNT_AMOUNT = "할인 양을 입력해주세요."; private static final String INPUT_VOUCHER_UPDATE = "수정할 바우처 번호를 입력해주세요."; + private static final String INPUT_VOUCHER_DELETE = "삭제할 바우처 번호를 입력해주세요."; private static final Scanner SCANNER = new Scanner(System.in); public static Command inputCommand() { @@ -47,10 +48,19 @@ private static int inputAmount() { return inputValue; } - public static UUID inputUpdateVoucherId(List vouchers) { + public static UUID inputVoucherUpdate(List vouchers) { System.out.println(INPUT_VOUCHER_UPDATE); + return inputVoucherId(vouchers); + } + + private static UUID inputVoucherId(List vouchers) { String selectedVoucherNumber = SCANNER.nextLine(); VoucherResponse voucherResponse = vouchers.get(Integer.parseInt(selectedVoucherNumber) - 1); return voucherResponse.getId(); } + + public static UUID inputVoucherDelete(List vouchers) { + System.out.println(INPUT_VOUCHER_DELETE); + return inputVoucherId(vouchers); + } } diff --git a/src/main/java/com/programmers/vouchermanagement/view/OutputView.java b/src/main/java/com/programmers/vouchermanagement/view/OutputView.java index c7959d1e5b..eaec94513c 100644 --- a/src/main/java/com/programmers/vouchermanagement/view/OutputView.java +++ b/src/main/java/com/programmers/vouchermanagement/view/OutputView.java @@ -14,6 +14,7 @@ public class OutputView { private static final String LINE = "ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ"; private static final String VOUCHER_TABLE_TITLE = " 번호 | 바우처 ID | 할인 유형 | 할인 양 "; private static final String VOUCHER_UPDATE = "================= 바우처 수정 ================="; + private static final String VOUCHER_DELETE = "================= 바우처 삭제 ================="; public static void showCommand() { System.out.println(VOUCHER_PROGRAM); @@ -50,4 +51,9 @@ public static void showVoucherUpdate(List vouchers) { System.out.println(VOUCHER_UPDATE); showVoucher(vouchers); } + + public static void showVoucherDelete(List vouchers) { + System.out.println(VOUCHER_DELETE); + showVoucher(vouchers); + } } diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherService.java b/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherService.java index f37ec509b2..e49bc8713a 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherService.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/application/VoucherService.java @@ -45,4 +45,8 @@ public void updateVoucher(VoucherUpdateRequest request) { Voucher voucher = new Voucher(id, discountPolicy); voucherRepository.update(voucher); } + + public void deleteVoucher(UUID id) { + voucherRepository.deleteById(id); + } } diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/presentation/VoucherController.java b/src/main/java/com/programmers/vouchermanagement/voucher/presentation/VoucherController.java index da59781133..198df1be2b 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/presentation/VoucherController.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/presentation/VoucherController.java @@ -8,6 +8,7 @@ import org.springframework.stereotype.Controller; import java.util.List; +import java.util.UUID; @Controller @RequiredArgsConstructor @@ -26,4 +27,8 @@ public List getVouchers() { public void updateVoucher(VoucherUpdateRequest request) { voucherService.updateVoucher(request); } + + public void deleteVoucher(UUID id) { + voucherService.deleteVoucher(id); + } } From 0cc589bfc02d646bb9d4793c63206f607b2f2bb9 Mon Sep 17 00:00:00 2001 From: Yiseul Park Date: Sat, 8 Jul 2023 21:55:06 +0900 Subject: [PATCH 26/28] =?UTF-8?q?refactor:=20DiscountPolicy=20=EC=B6=94?= =?UTF-8?q?=EC=83=81=ED=81=B4=EB=9E=98=EC=8A=A4=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../voucher/domain/DiscountPolicy.java | 22 +++++++++--- .../domain/FixedAmountDiscountPolicy.java | 34 ++++--------------- .../voucher/domain/PercentDiscountPolicy.java | 32 +++-------------- .../VoucherManagementApplicationTests.java | 13 ------- 4 files changed, 29 insertions(+), 72 deletions(-) delete mode 100644 src/test/java/com/programmers/vouchermanagement/VoucherManagementApplicationTests.java diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountPolicy.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountPolicy.java index 9766ddb3f2..ad200aa30e 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountPolicy.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountPolicy.java @@ -1,10 +1,24 @@ package com.programmers.vouchermanagement.voucher.domain; -public interface DiscountPolicy { +import lombok.EqualsAndHashCode; - int getAmount(); +@EqualsAndHashCode +public abstract class DiscountPolicy { - DiscountType getType(); + private final int amount; - int discount(int originalPrice); + DiscountPolicy(int amount) { + validateAmount(amount); + this.amount = amount; + } + + abstract void validateAmount(int amount); + + public int getAmount() { + return amount; + } + + public abstract DiscountType getType(); + + public abstract int discount(int originalPrice); } diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicy.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicy.java index 0967988f0c..c1062d7cf0 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicy.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicy.java @@ -1,27 +1,20 @@ package com.programmers.vouchermanagement.voucher.domain; -public class FixedAmountDiscountPolicy implements DiscountPolicy { +public class FixedAmountDiscountPolicy extends DiscountPolicy { public static final int MIN_AMOUNT = 1; - private final int amount; - public FixedAmountDiscountPolicy(int amount) { - validationAmount(amount); - this.amount = amount; + super(amount); } - private void validationAmount(int amount) { + @Override + void validateAmount(int amount) { if (amount < MIN_AMOUNT) { throw new IllegalArgumentException("The minimum discount amount is 1."); } } - @Override - public int getAmount() { - return amount; - } - @Override public DiscountType getType() { return DiscountType.FIX; @@ -29,24 +22,9 @@ public DiscountType getType() { @Override public int discount(int originalPrice) { - if (amount > originalPrice) { + if (getAmount() > originalPrice) { return 0; } - return originalPrice - amount; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - FixedAmountDiscountPolicy that = (FixedAmountDiscountPolicy) o; - - return amount == that.amount; - } - - @Override - public int hashCode() { - return amount; + return originalPrice - getAmount(); } } diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicy.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicy.java index 62aa6fc290..8922ee5d88 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicy.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicy.java @@ -2,29 +2,22 @@ import java.math.BigDecimal; -public class PercentDiscountPolicy implements DiscountPolicy { +public class PercentDiscountPolicy extends DiscountPolicy { public static final int MIN_PERCENT = 1; public static final int MAX_PERCENT = 100; - private final int amount; - public PercentDiscountPolicy(int amount) { - validationAmount(amount); - this.amount = amount; + super(amount); } - private void validationAmount(int amount) { + @Override + void validateAmount(int amount) { if (MIN_PERCENT > amount || amount > MAX_PERCENT) { throw new IllegalArgumentException("The discount percentage must be between 1 and 100%."); } } - @Override - public int getAmount() { - return amount; - } - @Override public DiscountType getType() { return DiscountType.PERCENT; @@ -37,23 +30,8 @@ public int discount(int originalPrice) { } private int calculateDiscountedAmount(int originalPrice) { - BigDecimal percent = BigDecimal.valueOf(amount).divide(BigDecimal.valueOf(MAX_PERCENT)); + BigDecimal percent = BigDecimal.valueOf(getAmount()).divide(BigDecimal.valueOf(MAX_PERCENT)); BigDecimal discountedAmount = percent.multiply(BigDecimal.valueOf(originalPrice)); return discountedAmount.intValue(); } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - PercentDiscountPolicy that = (PercentDiscountPolicy) o; - - return amount == that.amount; - } - - @Override - public int hashCode() { - return amount; - } } diff --git a/src/test/java/com/programmers/vouchermanagement/VoucherManagementApplicationTests.java b/src/test/java/com/programmers/vouchermanagement/VoucherManagementApplicationTests.java deleted file mode 100644 index 85414204ad..0000000000 --- a/src/test/java/com/programmers/vouchermanagement/VoucherManagementApplicationTests.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.programmers.vouchermanagement; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class VoucherManagementApplicationTests { - - @Test - void contextLoads() { - } - -} From c20e8a4984f092dc6edd4e769b3006c7727765a8 Mon Sep 17 00:00:00 2001 From: Yiseul Park Date: Sat, 8 Jul 2023 22:01:19 +0900 Subject: [PATCH 27/28] =?UTF-8?q?refactor:=20=EB=A1=AC=EB=B3=B5=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../customer/domain/Customer.java | 8 +--- .../voucher/domain/DiscountPolicy.java | 6 +-- .../voucher/domain/Voucher.java | 39 ++++--------------- 3 files changed, 11 insertions(+), 42 deletions(-) diff --git a/src/main/java/com/programmers/vouchermanagement/customer/domain/Customer.java b/src/main/java/com/programmers/vouchermanagement/customer/domain/Customer.java index 2403093a14..9aa0dfc029 100644 --- a/src/main/java/com/programmers/vouchermanagement/customer/domain/Customer.java +++ b/src/main/java/com/programmers/vouchermanagement/customer/domain/Customer.java @@ -1,5 +1,6 @@ package com.programmers.vouchermanagement.customer.domain; +import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -7,6 +8,7 @@ @Getter @EqualsAndHashCode +@AllArgsConstructor public class Customer { private final UUID id; @@ -19,12 +21,6 @@ public Customer(String name, CustomerType type) { this.type = type; } - public Customer(UUID id, String name, CustomerType type) { - this.id = id; - this.name = name; - this.type = type; - } - public void changeType(CustomerType type) { this.type = type; } diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountPolicy.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountPolicy.java index ad200aa30e..0909826f43 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountPolicy.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountPolicy.java @@ -1,7 +1,9 @@ package com.programmers.vouchermanagement.voucher.domain; import lombok.EqualsAndHashCode; +import lombok.Getter; +@Getter @EqualsAndHashCode public abstract class DiscountPolicy { @@ -14,10 +16,6 @@ public abstract class DiscountPolicy { abstract void validateAmount(int amount); - public int getAmount() { - return amount; - } - public abstract DiscountType getType(); public abstract int discount(int originalPrice); diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/Voucher.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/Voucher.java index d145bf1a5c..42b8c98733 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/Voucher.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/Voucher.java @@ -1,8 +1,14 @@ package com.programmers.vouchermanagement.voucher.domain; -import java.util.Objects; +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; + import java.util.UUID; +@Getter +@EqualsAndHashCode +@AllArgsConstructor public class Voucher { private final UUID id; @@ -13,19 +19,6 @@ public Voucher(DiscountPolicy discountPolicy) { this.discountPolicy = discountPolicy; } - public Voucher(UUID id, DiscountPolicy discountPolicy) { - this.id = id; - this.discountPolicy = discountPolicy; - } - - public UUID getId() { - return id; - } - - public DiscountPolicy getDiscountPolicy() { - return discountPolicy; - } - public int discount(int originalPrice) { return discountPolicy.discount(originalPrice); } @@ -33,22 +26,4 @@ public int discount(int originalPrice) { public void changeDiscountPolicy(DiscountPolicy discountPolicy) { this.discountPolicy = discountPolicy; } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Voucher voucher = (Voucher) o; - - if (!Objects.equals(id, voucher.id)) return false; - return Objects.equals(discountPolicy, voucher.discountPolicy); - } - - @Override - public int hashCode() { - int result = id != null ? id.hashCode() : 0; - result = 31 * result + (discountPolicy != null ? discountPolicy.hashCode() : 0); - return result; - } } From acfc48f32f314815db8478d1a825a9ddf761638c Mon Sep 17 00:00:00 2001 From: Yiseul Park Date: Sun, 9 Jul 2023 01:17:43 +0900 Subject: [PATCH 28/28] =?UTF-8?q?feat:=20=EC=BB=A4=EC=8A=A4=ED=85=80=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vouchermanagement/customer/domain/CustomerType.java | 4 +++- .../customer/exception/InvalidCustomerTypeException.java | 7 +++++++ .../vouchermanagement/voucher/domain/DiscountType.java | 3 ++- .../voucher/domain/FixedAmountDiscountPolicy.java | 4 +++- .../voucher/domain/PercentDiscountPolicy.java | 4 +++- .../voucher/exception/InvalidDiscountAmountException.java | 7 +++++++ .../voucher/exception/InvalidDiscountTypeException.java | 7 +++++++ .../customer/domain/CustomerTypeTest.java | 3 ++- .../vouchermanagement/voucher/domain/DiscountTypeTest.java | 3 ++- .../voucher/domain/FixedAmountDiscountPolicyTest.java | 5 +++-- .../voucher/domain/PercentDiscountPolicyTest.java | 5 +++-- 11 files changed, 42 insertions(+), 10 deletions(-) create mode 100644 src/main/java/com/programmers/vouchermanagement/customer/exception/InvalidCustomerTypeException.java create mode 100644 src/main/java/com/programmers/vouchermanagement/voucher/exception/InvalidDiscountAmountException.java create mode 100644 src/main/java/com/programmers/vouchermanagement/voucher/exception/InvalidDiscountTypeException.java diff --git a/src/main/java/com/programmers/vouchermanagement/customer/domain/CustomerType.java b/src/main/java/com/programmers/vouchermanagement/customer/domain/CustomerType.java index 32b4545421..6fc1cddfb2 100644 --- a/src/main/java/com/programmers/vouchermanagement/customer/domain/CustomerType.java +++ b/src/main/java/com/programmers/vouchermanagement/customer/domain/CustomerType.java @@ -1,5 +1,7 @@ package com.programmers.vouchermanagement.customer.domain; +import com.programmers.vouchermanagement.customer.exception.InvalidCustomerTypeException; + public enum CustomerType { BLACK, WHITE; @@ -7,7 +9,7 @@ public static CustomerType from(String type) { try { return valueOf(type.toUpperCase()); } catch (IllegalArgumentException e) { - throw new IllegalArgumentException("잘못된 고객 타입입니다."); + throw new InvalidCustomerTypeException("잘못된 고객 타입입니다."); } } } diff --git a/src/main/java/com/programmers/vouchermanagement/customer/exception/InvalidCustomerTypeException.java b/src/main/java/com/programmers/vouchermanagement/customer/exception/InvalidCustomerTypeException.java new file mode 100644 index 0000000000..3a57a94cb0 --- /dev/null +++ b/src/main/java/com/programmers/vouchermanagement/customer/exception/InvalidCustomerTypeException.java @@ -0,0 +1,7 @@ +package com.programmers.vouchermanagement.customer.exception; + +public class InvalidCustomerTypeException extends RuntimeException { + public InvalidCustomerTypeException(String message) { + super(message); + } +} diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountType.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountType.java index dd79f5be28..fd92e1487e 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountType.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/DiscountType.java @@ -1,5 +1,6 @@ package com.programmers.vouchermanagement.voucher.domain; +import com.programmers.vouchermanagement.voucher.exception.InvalidDiscountTypeException; import lombok.Getter; import java.util.Collections; @@ -34,7 +35,7 @@ public static DiscountType from(String number) { if (DISCOUNT_TYPE_MAP.containsKey(number)) { return DISCOUNT_TYPE_MAP.get(number); } - throw new IllegalArgumentException("존재하지 않는 할인 유형 입니다."); + throw new InvalidDiscountTypeException("존재하지 않는 할인 유형 입니다."); } public DiscountPolicy createDiscountPolicy(int amount) { diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicy.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicy.java index c1062d7cf0..443af3a97f 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicy.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicy.java @@ -1,5 +1,7 @@ package com.programmers.vouchermanagement.voucher.domain; +import com.programmers.vouchermanagement.voucher.exception.InvalidDiscountAmountException; + public class FixedAmountDiscountPolicy extends DiscountPolicy { public static final int MIN_AMOUNT = 1; @@ -11,7 +13,7 @@ public FixedAmountDiscountPolicy(int amount) { @Override void validateAmount(int amount) { if (amount < MIN_AMOUNT) { - throw new IllegalArgumentException("The minimum discount amount is 1."); + throw new InvalidDiscountAmountException("고정할인금액은 최소 1원 이상이여야 합니다."); } } diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicy.java b/src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicy.java index 8922ee5d88..ae162bb217 100644 --- a/src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicy.java +++ b/src/main/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicy.java @@ -1,5 +1,7 @@ package com.programmers.vouchermanagement.voucher.domain; +import com.programmers.vouchermanagement.voucher.exception.InvalidDiscountAmountException; + import java.math.BigDecimal; public class PercentDiscountPolicy extends DiscountPolicy { @@ -14,7 +16,7 @@ public PercentDiscountPolicy(int amount) { @Override void validateAmount(int amount) { if (MIN_PERCENT > amount || amount > MAX_PERCENT) { - throw new IllegalArgumentException("The discount percentage must be between 1 and 100%."); + throw new InvalidDiscountAmountException("할인률은 1에서 100 사이여야 합니다."); } } diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/exception/InvalidDiscountAmountException.java b/src/main/java/com/programmers/vouchermanagement/voucher/exception/InvalidDiscountAmountException.java new file mode 100644 index 0000000000..35d3e101ad --- /dev/null +++ b/src/main/java/com/programmers/vouchermanagement/voucher/exception/InvalidDiscountAmountException.java @@ -0,0 +1,7 @@ +package com.programmers.vouchermanagement.voucher.exception; + +public class InvalidDiscountAmountException extends RuntimeException { + public InvalidDiscountAmountException(String message) { + super(message); + } +} diff --git a/src/main/java/com/programmers/vouchermanagement/voucher/exception/InvalidDiscountTypeException.java b/src/main/java/com/programmers/vouchermanagement/voucher/exception/InvalidDiscountTypeException.java new file mode 100644 index 0000000000..4018ec998d --- /dev/null +++ b/src/main/java/com/programmers/vouchermanagement/voucher/exception/InvalidDiscountTypeException.java @@ -0,0 +1,7 @@ +package com.programmers.vouchermanagement.voucher.exception; + +public class InvalidDiscountTypeException extends RuntimeException { + public InvalidDiscountTypeException(String message) { + super(message); + } +} diff --git a/src/test/java/com/programmers/vouchermanagement/customer/domain/CustomerTypeTest.java b/src/test/java/com/programmers/vouchermanagement/customer/domain/CustomerTypeTest.java index 0feca8e80a..d6383e7807 100644 --- a/src/test/java/com/programmers/vouchermanagement/customer/domain/CustomerTypeTest.java +++ b/src/test/java/com/programmers/vouchermanagement/customer/domain/CustomerTypeTest.java @@ -1,5 +1,6 @@ package com.programmers.vouchermanagement.customer.domain; +import com.programmers.vouchermanagement.customer.exception.InvalidCustomerTypeException; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -49,7 +50,7 @@ void fromException() { // given & then assertThatThrownBy(() -> CustomerType.from(type)) - .isInstanceOf(IllegalArgumentException.class) + .isInstanceOf(InvalidCustomerTypeException.class) .hasMessage("잘못된 고객 타입입니다."); } } \ No newline at end of file diff --git a/src/test/java/com/programmers/vouchermanagement/voucher/domain/DiscountTypeTest.java b/src/test/java/com/programmers/vouchermanagement/voucher/domain/DiscountTypeTest.java index 4603db3bd6..8d3e3ab818 100644 --- a/src/test/java/com/programmers/vouchermanagement/voucher/domain/DiscountTypeTest.java +++ b/src/test/java/com/programmers/vouchermanagement/voucher/domain/DiscountTypeTest.java @@ -1,5 +1,6 @@ package com.programmers.vouchermanagement.voucher.domain; +import com.programmers.vouchermanagement.voucher.exception.InvalidDiscountTypeException; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -48,7 +49,7 @@ void from_exception() { // when & then assertThatThrownBy(() -> DiscountType.from(number)) - .isInstanceOf(IllegalArgumentException.class) + .isInstanceOf(InvalidDiscountTypeException.class) .hasMessage("존재하지 않는 할인 유형 입니다."); } } \ No newline at end of file diff --git a/src/test/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicyTest.java b/src/test/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicyTest.java index ae97d5caf4..5818627cf6 100644 --- a/src/test/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicyTest.java +++ b/src/test/java/com/programmers/vouchermanagement/voucher/domain/FixedAmountDiscountPolicyTest.java @@ -1,5 +1,6 @@ package com.programmers.vouchermanagement.voucher.domain; +import com.programmers.vouchermanagement.voucher.exception.InvalidDiscountAmountException; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.params.ParameterizedTest; @@ -29,8 +30,8 @@ void isMoreThanMinAmount(int amount) { void lessThanMinAmount(int amount) { // when & then assertThatThrownBy(() -> new FixedAmountDiscountPolicy(amount)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("The minimum discount amount is 1."); + .isInstanceOf(InvalidDiscountAmountException.class) + .hasMessage("고정할인금액은 최소 1원 이상이여야 합니다."); } } diff --git a/src/test/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicyTest.java b/src/test/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicyTest.java index e8b6e9640a..e8ac5fd174 100644 --- a/src/test/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicyTest.java +++ b/src/test/java/com/programmers/vouchermanagement/voucher/domain/PercentDiscountPolicyTest.java @@ -1,5 +1,6 @@ package com.programmers.vouchermanagement.voucher.domain; +import com.programmers.vouchermanagement.voucher.exception.InvalidDiscountAmountException; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.params.ParameterizedTest; @@ -29,8 +30,8 @@ void isBetween1And100(int amount) { void isNotBetween1And100(int amount) { // when & then assertThatThrownBy(() -> new PercentDiscountPolicy(amount)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("The discount percentage must be between 1 and 100%."); + .isInstanceOf(InvalidDiscountAmountException.class) + .hasMessage("할인률은 1에서 100 사이여야 합니다."); } }