์ฃผ๋ฌธ๊ณผ ํ ์ธ ๋๋ฉ์ธ ์ค๊ณ
์ฃผ๋ฌธ๊ณผ ํ ์ธ ์ ์ฑ
- ํ์์ ์ํ์ ์ฃผ๋ฌธํ ์ ์๋ค.
- ํ์ ๋ฑ๊ธ์ ๋ฐ๋ผ ํ ์ธ ์ ์ฑ ์ ์ ์ฉํ ์ ์๋ค.
- ํ ์ธ ์ ์ฑ ์ ๋ชจ๋ VIP๋ 1000์์ ํ ์ธํด์ฃผ๋ ๊ณ ์ ๊ธ์ก ํ ์ธ์ ์ ์ฉํด๋ฌ๋ผ. (๋์ค์ ๋ณ๊ฒฝ ๋ ์ ์๋ค.)
- ํ ์ธ ์ ์ฑ ์ ๋ณ๊ฒฝ ๊ฐ๋ฅ์ฑ์ด ๋๋ค. ํ์ฌ์ ๊ธฐ๋ณธ ํ ์ธ ์ ์ฑ ์ ์์ง ์ ํ์ง ๋ชปํ๊ณ , ์คํ ์ง์ ๊น์ง ๊ณ ๋ฏผ์ ๋ฏธ๋ฃจ๊ณ ์ถ๋ค. ์ต์ ์ ๊ฒฝ์ฐ ํ ์ธ์ ์ ์ฉํ์ง ์์ ์ ๋ ์๋ค. (๋ฏธํ์ )
์ฃผ๋ฌธ ๋๋ฉ์ธ ํ๋ ฅ, ์ญํ , ์ฑ ์
1. ์ฃผ๋ฌธ ์์ฑ: ํด๋ผ์ด์ธํธ๋ ์ฃผ๋ฌธ ์๋น์ค์ ์ฃผ๋ฌธ ์์ฑ์ ์์ฒญํ๋ค.
2. ํ์ ์กฐํ: ํ ์ธ์ ์ํด์๋ ํ์ ๋ฑ๊ธ์ด ํ์ํ๋ค. ๊ทธ๋์ ์ฃผ๋ฌธ ์๋น์ค๋ ํ์ ์ ์ฅ์์์ ํ์์ ์กฐํํ๋ค.
3. ํ ์ธ ์ ์ฉ: ์ฃผ๋ฌธ ์๋น์ค๋ ํ์ ๋ฑ๊ธ์ ๋ฐ๋ฅธ ํ ์ธ ์ฌ๋ถ๋ฅผ ํ ์ธ ์ ์ฑ ์ ์์ํ๋ค.
4. ์ฃผ๋ฌธ ๊ฒฐ๊ณผ ๋ฐํ: ์ฃผ๋ฌธ ์๋น์ค๋ ํ ์ธ ๊ฒฐ๊ณผ๋ฅผ ํฌํจํ ์ฃผ๋ฌธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ค.
์ฃผ๋ฌธ ๋๋ฉ์ธ ์ ์ฒด
์ญํ ๊ณผ ๊ตฌํ์ ๋ถ๋ฆฌํด์ ์์ ๋กญ๊ฒ ๊ตฌํ ๊ฐ์ฒด๋ฅผ ์กฐ๋ฆฝํ ์ ์๊ฒ ์ค๊ณํ๋ค.
ํ ์ธ ์ ์ฑ ์ญํ
๊ตฌํ -> ์ ์ก ํ ์ธ ์ ์ฑ
๊ตฌํ -> ์ ๋ฅ ํ ์ธ ์ ์ฑ
๋๋ถ์ ํ์ ์ ์ฅ์๋ ๋ฌผ๋ก ์ด๊ณ , ํ ์ธ ์ ์ฑ ๋ ์ ์ฐํ๊ฒ ๋ณ๊ฒฝํ ์ ์๋ค.
์ฃผ๋ฌธ ๋๋ฉ์ธ ํด๋์ค ๋ค์ด์ด๊ทธ๋จ
์ญํ (interface)๊ณผ ๊ตฌํ์ ๋ถ๋ฆฌ
ํ ์ธ ์ ์ฑ ์ญํ (DiscountPolicy)
๊ตฌํ -> ์ ์ก ํ ์ธ ์ ์ฑ FixDiscountPolicy
๊ตฌํ -> ์ ๋ฅ ํ ์ธ ์ ์ฑ RateDiscountPolicy
์ฃผ๋ฌธ ๋๋ฉ์ธ ๊ฐ์ฒด ๋ค์ด์ด๊ทธ๋จ 11
ํ์์ ๋ฉ๋ชจ๋ฆฌ์์ ์กฐํํ๊ณ , ์ ์ก ํ ์ธ ์ ์ฑ (๊ณ ์ ๊ธ์ก)์ ์ง์ํด๋ ์ฃผ๋ฌธ ์๋น์ค๋ฅผ ๋ณ๊ฒฝํ์ง ์์๋ ๋๋ค.
์ญํ ๋ค์ ํ๋ ฅ ๊ด๊ณ๋ฅผ ๊ทธ๋๋ก ์ฌ์ฌ์ฉํ ์ ์๋ค.
์ฃผ๋ฌธ ๋๋ฉ์ธ ๊ฐ์ฒด ๋ค์ด์ด๊ทธ๋จ2
ํ์์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์๋ ์ค์ DB์์ ์กฐํํ๊ณ , ์ ๋ฅ ํ ์ธ ์ ์ฑ
(์ฃผ๋ฌธ ๊ธ์ก์ ๋ฐ๋ผ % ํ ์ธ)์ ์ง์ํด๋ ์ฃผ๋ฌธ ์๋น์ค๋ฅผ ๋ณ๊ฒฝํ์ง ์์๋ ๋๋ค.
ํ๋ ฅ ๊ด๊ณ๋ฅผ ๊ทธ๋๋ก ์ฌ์ฌ์ฉํ ์ ์๋ค.
์ฃผ๋ฌธ๊ณผ ํ ์ธ ๋๋ฉ์ธ ๊ฐ๋ฐ
ํ ์ธ ์ ์ฑ ์ธํฐํ์ด์ค
package hello2.demo.discount;
import hello2.demo.member.Member;
public interface DiscountPolicy {
/**
* @return ํ ์ธ ๋์ ๊ธ์ก
*/
int discount(Member member, int price);
}
์ ์ก ํ ์ธ ์ ์ฑ ๊ตฌํ์ฒด
VIP๋ฉด 1000์ ํ ์ธ, ์๋๋ฉด ํ ์ธ ์์
package hello2.demo.discount;
import hello2.demo.member.Grade;
import hello2.demo.member.Member;
public class FixDiscountPolicy implements DiscountPolicy{
private int discountFixAmount = 1000; // 1000์ ํ ์ธ
@Override
public int discount(Member member, int price) {
if (member.getGrade() == Grade.VIP) {
return discountFixAmount;
} else {
return 0;
}
}
}
์ฃผ๋ฌธ ์ํฐํฐ
package hello2.demo.order;
public class Order {
private Long memberId;
private String itemName;
private int itemPrice;
private int discountPrice;
public Order(Long memberId, String itemName, int itemPrice, int discountPrice) {
this.memberId = memberId;
this.itemName = itemName;
this.itemPrice = itemPrice;
this.discountPrice = discountPrice;
}
public int calculatePrice(){ // ์ต์ข
๊ณ์ฐ๋ ๊ธ์ก
return itemPrice - discountPrice;
}
public Long getMemberId() {
return memberId;
}
public void setMemberId(Long memberId) {
this.memberId = memberId;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public int getItemPrice() {
return itemPrice;
}
public void setItemPrice(int itemPrice) {
this.itemPrice = itemPrice;
}
public int getDiscountPrice() {
return discountPrice;
}
public void setDiscountPrice(int discountPrice) {
this.discountPrice = discountPrice;
}
@Override
public String toString() {
return "Order{" +
"memberId=" + memberId +
", itemName='" + itemName + '\'' +
", itemPrice=" + itemPrice +
", discountPrice=" + discountPrice +
'}';
} // ๊ฐ์ฒด๋ฅผ ์ถ๋ ฅํ๋ฉด toString ํธ์ถ(๊ฒฐ๊ณผ๊ฐ ์ถ๋ ฅ)
}
์ฃผ๋ฌธ ์๋น์ค ์ธํฐํ์ด์ค
package hello2.demo.order;
public interface OrderService {
Order createOrder(Long memberId, String itemName, int itemPrice);
}
์ฃผ๋ฌธ ์๋น์ค ๊ตฌํ์ฒด
package hello2.demo.order;
import hello2.demo.discount.DiscountPolicy;
import hello2.demo.discount.FixDiscountPolicy;
import hello2.demo.member.Member;
import hello2.demo.member.MemberRepository;
import hello2.demo.member.MemoryMemberRepository;
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository = new MemoryMemberRepository();
private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
@Override
public Order createOrder(Long memberId, String itemName, int itemPrice) {
Member member = memberRepository.findById(memberId);
int discountPrice = discountPolicy.discount(member, itemPrice);
return new Order(memberId, itemName, itemPrice, discountPrice);
}
}
์ฃผ๋ฌธ ์์ฑ ์์ฒญ์ด ์ค๋ฉด (createOrder())
ํ์ ์ ๋ณด๋ฅผ ์กฐํํ๊ณ (findById(memberId)
ํ ์ธ ์ ์ฑ ์ ์ ์ฉํ ๋ค์ discount(member, itemPrice). // discountPrice --> member์ id๊ฐ vip์ด๋ฉด 1000
์ฃผ๋ฌธ ๊ฐ์ฒด๋ฅผ ์์ฑํด์ ๋ฐํํ๋ค. ( return new Order() )
๋ฉ๋ชจ๋ฆฌ ํ์ ๋ฆฌํฌ์งํ ๋ฆฌ์, ๊ณ ์ ๊ธ์ก ํ ์ธ ์ ์ฑ ์ ๊ตฌํ์ฒด๋ก ์์ฑํ๋ค.
์ฃผ๋ฌธ๊ณผ ํ ์ธ ๋๋ฉ์ธ ์คํ๊ณผ ํ ์คํธ
์ฃผ๋ฌธ๊ณผ ํ ์ธ ์ ์ฑ ์คํ
package hello2.demo;
import hello2.demo.discount.DiscountPolicy;
import hello2.demo.discount.FixDiscountPolicy;
import hello2.demo.member.*;
import hello2.demo.order.Order;
import hello2.demo.order.OrderService;
import hello2.demo.order.OrderServiceImpl;
public class OrderApp {
public static void main(String[] args) {
OrderService orderService = new OrderServiceImpl();
MemberService memberService = new MemberServiceImpl();
Long memberId = 1L;
Member member = new Member(1L,"memberA",Grade.VIP);
memberService.join(member);
Order order = orderService.createOrder(memberId,"itemA",10000);
System.out.println("order = " + order);
System.out.println("order.calculatePrice = " + order.calculatePrice());
}
}
ํ ์ธ ๊ธ์ก์ด ์ ์ถ๋ ฅ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
์ ํ๋ฆฌ์ผ์ด์
๋ก์ง์ผ๋ก ์ด๋ ๊ฒ ํ
์คํธํ๋ ๊ฒ์ ์ข์ ๋ฐฉ๋ฒ์ด ์๋๋ค. JUnit ํ
์คํธ๋ฅผ ์ฌ์ฉํ์.
์ฃผ๋ฌธ๊ณผ ํ ์ธ ์ ์ฑ ํ ์คํธ
package hello2.demo.order;
import hello2.demo.member.Grade;
import hello2.demo.member.Member;
import hello2.demo.member.MemberService;
import hello2.demo.member.MemberServiceImpl;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
public class OrderServiceTest {
OrderService orderService = new OrderServiceImpl();
MemberService memberService = new MemberServiceImpl();
@Test
void createOrder() {
Long memberId = 1L;
Member member = new Member(1L, "memberA", Grade.VIP);
memberService.join(member);
Order order = orderService.createOrder(memberId, "itemA", 10000);
Assertions.assertThat(order.getDiscountPrice()).isEqualTo(1000);
}
}