<aside> 💡 Github 주소
https://github.com/yeonssu/BurgerQueen-ordersysetm
</aside>
DiscountPolicy 인터페이스 정의
public interface DiscountPolicy{
int calculateDiscountedPrice(int price);
}
FixedRateDiscountPolicy클래스와 FixedAmountDiscountPolicy 클래스에 DiscountPolicy 인터페이스를 구현
public class FixedRateDiscountPolicy implements DiscountPolicy { ... }
public class FixedAmountDiscountPolicy implements DiscountPolicy { ... }
수강생할인 클래스와 청소년할인 클래스에 FixedRateDiscountPolicy와 FixedAmountDiscountPolicy 관련 코드를 DiscountPolicy 인터페이스 구현 코드로 수정
public class CozDiscountCondition{
...
~~private FixedRateDiscountPolicy fixedRateDiscountPolicy = new FixedRateDiscountPolicy(10);~~
private DiscountPolicy discountPolicy;
//생성자 추가
public CozDiscountCondition(DiscountPolicy discountPolicy){
this.discountPolicy = discountPolicy;
}
public int applyDiscount(int price){
~~return fixedRateDiscountPolicy.calculateDiscountPrice(price);~~
return discountPolicy.calculateDiscountedPrice(price);
}
}
public class KidDiscountCondition{
...
~~private FixedAmountDiscountPolicy fixedAmountDiscountPolicy = new FixedAmountDiscountPolicy(500);~~
private DiscountPolicy discountPolicy;
//생성자 추가
public KidDiscountCondition(DiscountPolicy discountPolicy){
this.discountPoslicy = discountPolicy;
}
public int applyDiscount(int price){
~~return fixedAmountDiscountPolicy.calculateDiscountPrice(price);~~
return discountPolicy.calculateDiscountedPrice(price);
}
}
makdOrder() 메서드 수정(의존성 주입, 스스로 구현 클래스를 결정하지 않는다. 인터페이스에 의존하여 구현클래스를 변경하여도 영향받지 않는다)
public void makeOrder(){
~~CozDiscountCondition cozDiscountCondition = new CozDiscountCondition();~~
CozDiscountCondition cozDiscountCondition = new CozDiscountCondition(new FixedRateDiscountPolicy(10));
~~KidDiscountCondition kidDiscountCondition = new KidDiscountCondition();~~
KidDiscountCondition kidDiscountCondition = new KidDiscountCondition(new FixedAmountDiscountPolicy(500));
...
}
DiscountCondition 인터페이스 정의
public interface DiscountCondition{
void checkDiscountCondition();
int applyDiscount(int price);
boolean isSatisfied();
}
CozDiscountCondition클래스와 KidDiscountCondition클래스에 DiscountCondition 인터페이스 구현
public class CozDiscountCondition implements DiscountCondition { ... }
public class KidDiscountCondition implements DiscountCondition { ... }
Order 클래스 내부에 DiscountCondition 배열 정의, start()메서드에서 각 객체 생성
public class Order{
private DiscountCondition[] discountConditions;
//생성자 수정
public Order(Cart cart, DiscountCondition[] discountConditions){
this.cart = cart;
this.discountConditions = discountConditions;
}
...
public void start(){
...
Order order = new Order(cart, new DiscountCondition[]{
new CozDiscountCondition(new FixedRateDiscountPolicy(10)),
new KidDiscountCondition(new FixedAmountDiscountPolicy(500))
});
...
}
}
makdOrder() 메서드 수정(Order클래스에서 객체를 생성하므로 checkDiscountCondition()과 applyDiscount()만 실행하면 된다)
public class Order{
...
public void makeOrder(){
~~CozDiscountCondition cozDiscountCondition = new CozDiscountCondition(new FixedRateDiscountPolicy(10));
KidDiscountCondition kidDiscountCondition = new KidDiscountCondition(new FixedAmountDiscountPolicy(500));
cozDiscountCondition.checkDiscountCondition();
kidDiscountCondition.checkDiscountCondition();
int totalPrice = cart.calculateTotalPrice();
int finalPrice = totalPrice;
if (cozDiscountCondition.isSatisfied()) finalPrice = cozDiscountCondition.applyDiscount(finalPrice);
if (kidDiscountCondition.isSatisfied()) finalPrice = kidDiscountCondition.applyDiscount(finalPrice);~~
int totalPrice = cart.calculateTotalPrice();
int finalPrice = totalPrice;
for (DiscountCondition discountCondition : discountConditions) {
discountCondition.checkDiscountCondition();
if (discountCondition.isSatisfied()) finalPrice = discountCondition.applyDiscount(finalPrice);
}
...
}
...
}
각 클래스는 자신이 맡은 역할을 수행하도록 해야한다. 하지만 수정한 Order 클래스 내부 속 할인 관련 사항이 존재한다는 문제점이 생긴다.
Order 클래스 내부에 DiscountCondition배열과 관련 생성자, 할인조건검사메서드와 할인 적용 메서드가 반복문을 순회하고 있다
Discount 클래스 생성 후 관련 사항들을 모두 옮겨준다
public class Discount{
//Order클래스에 정의되어있는 배열과 생성자, 반복문 모두 옮겨준다
//배열
private DiscountCondition[] discountConditions;
//생성자
public Discount(DiscountCondition[] discountConditions){
this.discountConditions = discountConditions;
}
//반복문
public int discount(int price){
int discountPrice = price;
for (DiscountCondition discountCondition : discountConditions){
discountConditions.checkDiscountCondition();
if (discountConditions.isSatisfied()) discountPrice = discountCondition.applyDiscount(discountPrice);
}
return discountPrice;
}
}
Order클래스 수정
public class Order{
//배열 삭제 후 Discount클래스 정의, 생성자 변경
~~private DiscountCondition[] discountConditions;~~
~~public Order(Cart cart, DiscountCondition[] discountConditions){~~
~~this.cart = cart;
this.discountConditions = discountConditions;
}~~
private Discount discount;
public Order(Cart cart, Discount discount){
this.cart = cart;
this.discount = discount;
}
//start()메서드 내부의 배열관련
public void start(){
...
Order order = new Order(cart, new Discount{
~~Order order = new Order(cart, new DiscountCondition[]{~~
new CozDiscountCondition(new FixedRateDiscountPolicy(10)),
new KidDiscountCondition(new FixedAmountDiscountPolicy(500))
});
...
}
//makeOrder()메서드 내부에서 Discount클래스로 옮긴 반복분 삭제
public void makeOrder(){
int totalPrice = cart.calculateTotalPrice();
~~int finalPrice = totalPrice;~~
int finalPrice = discount.discount(totalPrice);
~~for (DiscountCondition discountCondition : discountConditions) {~~
~~discountCondition.checkDiscountCondition();~~
~~if (discountCondition.isSatisfied()) finalPrice = discountCondition.applyDiscount(finalPrice);~~
~~}~~
...
}
}