/* ์ด ๊ธ์ ๊น์ํ๋์ ๊ฐ์๋ฅผ ๋ณด๊ณ ์ ๋ฆฌํ๋ ค๊ณ ์์ฑํ ๊ธ์ ๋๋ค.
๊ฐ์ธ์ ์ธ ๊ณต๋ถ๋ฅผ ์ํด ์ฌ๋ฆฌ๋ ๊ธ์ด๋ฏ๋ก ์ค๊ฐ ์ค๊ฐ ์ฝ๋๋ ์๋ต๋์์ต๋๋ค. */
์คํ๋ง ํต์ฌ ์๋ฆฌ - ๊ธฐ๋ณธํธ - ์ธํ๋ฐ | ๊ฐ์
์คํ๋ง ์ ๋ฌธ์๊ฐ ์์ ๋ฅผ ๋ง๋ค์ด๊ฐ๋ฉด์ ์คํ๋ง์ ํต์ฌ ์๋ฆฌ๋ฅผ ์ดํดํ๊ณ , ์คํ๋ง ๊ธฐ๋ณธ๊ธฐ๋ฅผ ํ์คํ ๋ค์ง ์ ์์ต๋๋ค., ์คํ๋ง ํต์ฌ ์๋ฆฌ๋ฅผ ์ดํดํ๊ณ , ์ฑ์ฅํ๋ ๋ฐฑ์๋ ๊ฐ๋ฐ์๊ฐ ๋์ด๋ณด์ธ์! ๐ข
www.inflearn.com
์๋ก์ด ํ ์ธ ์ ์ฑ ๊ฐ๋ฐ
1. ์๊ตฌ์ฌํญ ๋ฐ ์ค๊ณ
โพ DiscountPolicy ์ธํฐํ์ด์ค๊ฐ ์์ผ๋ ๊ทธ๋ฅ RateDiscountPolicy๋ง ์ถ๊ฐ๋ก ๊ฐ๋ฐํ๋ฉด ๋จ.
2. RateDiscountPolicy ์ถ๊ฐ ๋ฐ ํ ์คํธ
RateDiscountPolicy
package hello.core.discount;
import hello.core.member.Grade;
import hello.core.member.Member;
public class RateDiscountPolicy implements DiscountPolicy{
private int discountPercent = 10;
@Override
public int discount(Member member, int price) {
if (member.getGrade() == Grade.VIP){
return price * discountPercent / 100;
}else {
return 0;
}
}
}
RateDiscountPolicyTest
package hello.core.discount;
import hello.core.member.Grade;
import hello.core.member.Member;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class RateDiscountPolicyTest {
RateDiscountPolicy discountPolicy = new RateDiscountPolicy();
@Test
@DisplayName("VIP๋ 10% ํ ์ธ์ด ์ ์ฉ๋์ด์ผ ํ๋ค.")
void vip_o(){
// given
Member member = new Member(1L, "memberVIP", Grade.VIP);
// when
int discount = discountPolicy.discount(member, 10000);
// then
Assertions.assertThat(discount).isEqualTo(1000);
}
@Test
@DisplayName("์ผ๋ฐ ํ์์ ํ ์ธ์ด ์ ์ฉ๋์ง ์์์ผ ํ๋ค.")
void vip_x(){
// given
Member member = new Member(2L, "memberBASIC", Grade.BASIC);
// when
int discount = discountPolicy.discount(member, 10000);
// then
Assertions.assertThat(discount).isEqualTo(0);
}
}
โพ @DisplayName ์ JUnit5 ๋ถํฐ ์ง์ํ๋ ๊ธฐ๋ฅ์ผ๋ก ํ ์คํธ ๋ฉ์๋์ ์ด๋ฆ์ ์ง์ ํด ์ค ์ ์๋ค.
โพ Assertions๋ static import ํ๋๊ฒ ์ข์ (Alt + Enter ๋๋ฅด๊ณ ๋๋ฒ์งธ๊บผ ์ ํ)
3. ์๋ก์ด ํ ์ธ ์ ์ฑ ์ ์ฉ
OrderServiceImpl
package hello.core.order;
import hello.core.discount.DiscountPolicy;
import hello.core.discount.FixDiscountPolicy;
import hello.core.discount.RateDiscountPolicy;
import hello.core.member.Member;
import hello.core.member.MemberRepository;
import hello.core.member.MemoryMemberRepository;
public class OrderServiceImpl implements OrderService{
private final MemberRepository memberRepository = new MemoryMemberRepository();
//private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
@Override
public Order createOrder(Long memberId, String itemName, int itemPrice) {
Member member = memberRepository.findById(memberId);
int discountPrice = discountPolicy.discount(member, itemPrice);
return new Order(memberId, itemName, itemPrice, discountPrice);
}
}
โพ ์๋ ์๋ discountPolicy๋ฅผ RateDiscountPolicy๋ก ๋ณ๊ฒฝํ๋ฉด ๋๋ค.
โพ But, ์ด๋ ๊ฒ ํ๋ฉด OCP, DIP๋ฅผ ์๋ฐํ๋ค.
โ DIP : OrderServiceImpl์ DiscountPolicy ์ธํฐํ์ด์ค์ ์์กดํ๋ฉฐ DIP๋ฅผ ์งํจ ๊ฒ ๊ฐ์ง๋ง ์์ธํ ๋ณด๋ฉด ๊ตฌํ ํด๋์ค์๋ ์์กดํ๊ณ ์์. DIP ์๋ฐ
โ OCP : ๊ทธ๋์ RateDiscountPolicy๋ก ๋ณ๊ฒฝํ๋ ค๋ฉด OrderServiceImpl์ ์์ค์ฝ๋๋ ํจ๊ป ๋ณ๊ฒฝํด์ผ ํ๋ค. OCP ์๋ฐ
4. ๋ฌธ์ ์ ํด๊ฒฐ
OrderServiceImpl
public class OrderServiceImpl implements OrderService{
private final MemberRepository memberRepository = new MemoryMemberRepository();
private DiscountPolicy discountPolicy;
@Override
public Order createOrder(Long memberId, String itemName, int itemPrice) {
Member member = memberRepository.findById(memberId);
int discountPrice = discountPolicy.discount(member, itemPrice);
return new Order(memberId, itemName, itemPrice, discountPrice);
}
}
โพ ๊ตฌ์ฒด์ ์์กดํ์ง ์๊ณ ์ถ์ํ์ธ ์ธํฐํ์ด์ค์ ์์กดํ๊ฒ ์ฝ๋ ๋ณ๊ฒฝ
โพ But ์ฝ๋๋ฅผ ์คํํ๋ฉด? NullPointerException ๋ฐ์ (discountPoliy๋ฅผ ๊ตฌ์ฒดํํ์ง ์์๊ธฐ๋๋ฌธ)
โ ํด๊ฒฐ๋ฐฉ์ : ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ค๋ฉด ๋๊ตฐ๊ฐ ํด๋ผ์ด์ธํธ์ธ 'OrderServiceImpl'์ 'DiscountPolicy'์ ๊ตฌํ ๊ฐ์ฒด๋ฅผ ๋์ ์์ฑํ๊ณ ์ฃผ์ ํด์ฃผ์ด์ผ ํจ.
๋ค์ ๊ฐ์์ ๊ณ์!