🌼복사생성자 적용을 통한 문제 해결
장바구니에 상품을 담을때 객체를 생성해서 담는 것이 아니라
객체의 참조값을 장바구니에 그대로 담게 된다
동일한 상품을 두 번 고르면서 옵션은 다르게 고르는 경우에 문제가 발생하는데
마지막으로 추가한 옵션 항목으로 덮어쓰이게 된다
★addToCart()에 새로운 상품객체를 생성하여 items에 담을 수 있도록 코드를 수정해야한다
얕은 복사 = 객체의 참조값을 복사하는 것
public void shallowCopyExample(Product product) {
Product newProduct = product; //객체가 위치한 힙메모리 주소값 동일한 객체를 가리킴
}
깊은 복사 = 내용이 동일하지만 참조값이 다른 새로운 객체를 생성하는것을 의미
public void DeepCopyExample(Product product) {
Product newProduct = new Product(product.getId, product.getName, ...);
}
새로운 객체를 만들도록 해야한다 먼저 Hambuger,Side,Drink 생성자를 오버로딩해서 추가해준다
addToCart()에서 새로운 객체를 생성해서 items에 추가하도록 해준다
composeSet()에서도 새로운 Side,Drink 인스턴스를 만들도록 수정
🌼주문 기능 구현
주문은 장바구니에 담긴 상품을 기반으로 이루어짐
cart객체를 통째로 정의
(할인코드는 나중에 추가)
makeOrder()
장바구니의 상품을 주문하는 기능 주문내역 출력
입력값 : items에 있는 상품을 단순하게 출력하는거라 필요x
반환값 : 출력이라 필요 x
접근제어자 : OrderApp에서 호출해야해서 public
public void makeOrder() {
System.out.println("[📣] 주문이 완료되었습니다. ");
System.out.println("[📣] 주문 내역은 다음과 같습니다. ");
System.out.println("-".repeat(60));
상품 상세 내역 출력
System.out.println("-".repeat(60));
System.out.printf("금액 합계 : %d원\n", 금액 합계 계산);
}
상세 내역 - cart.printCartItemDetails() / 금액합계 - cart.calculateTotalPrice()
접근범위를 private로 해둔것을 public이나 protected로 변경
OrderApp에 출력코드를 추가하고 테스트 해보기
🌼할인기능 구현
- 코드스테이츠 수강생에게 10% 할인 = 고정비율 할인 구현
- 20세 미만 청소년에게 500원 할인 = 고정금액 할인 구현
할인 정책
- 특정 할인조건에 부합하는 경우 ( 두가지 조건 모두 구현 )
할인 조건
- 상시 또는 불특정한 할인 이벤트 ( 변화에 유연한 대응 객체지향원리 )
객체지향적인 설계
할인정책 - 고정비율 할인 : FixedRateDiscoutPolicy 클래스
- 고정금액 할인 : FixedAmountDiscountPolicy 클래스
할인 조건 - 코드스테이츠 수강생 할인 : CozDiscountCondition 클래스
- 청소년 할인 : KidDiscountCondition 클래스
객체지향적인 설계 - 객체지향적이지 않은 코드를 설계후 변화와 확장에 유리하도록 리팩토링 해보기
-> 단점 파악해보기 / 리팩토링 후 장점 파악해보기
🌼할인 정책 구현
고정비율할인 FixedRateDiscountPolicy
고정금액할인 FixedAmountDiscountPolicy
🌼할인 조건 구현
1. 할인 조건 검사 : 할인 조건에 부합하는지 검사하고 부합여부 저장
2. 할인 정책 결정 : 할인 조건에 따라 적용할 할인 정책 지정
- 조건마다 검사 메서드가 필요 = checkDiscountCondition() 메서드
- 조건 검사의 결과를 저장 = isSatisfied 필드
- 조건에 부합하면 어떤 정책을 적용시킬지 지정 = fixedRateDiscountPolicy / fixedAmountDiscountPolicy 필드
- 할인 적용한 가격을 계산해서 사용자에게 보여줌 = applyDiscount() 메서드
CozDiscountCondition
코드스테이츠 수강생할인조건
checkDiscountCondition() & isSatisfied
조건에 부합하는지 물어보는 문장 출력
입력한 값의 부합여부를 isSatisfied의 값으로 저장
fixedRateDiscountPolicy
할인 정책은 할인조건에 따라 어떻게 할인을 해줄지 방법에 관한것
코드스테이츠 수강생 -> 고정비율 할인
청소년 -> 고정금액 할인
할인 정책은 할인 조건을 구현하는 클래스에 필드로 정의 되어야 한다
applyDiscount()
할인정책을 적용해서 실제할인 금액을 리턴해주는 메서드
calculateDiscountedPrice()의 결과값을 그대로 리턴
KidDiscountCondition
청소년할인조건
🌼할인 기능 적용
주문하기 눌렀을때 적용이 되는 기능
Order에서 조건을 묻고 할인을 적용해주는 메서드 호출
checkDiscountCondition() / applyDiscount()
🌼문제점 분석
변화와 확장에 취약
코드간 결합도가 높아 요구사항이 변경 되었을때
수정해주어야할 코드가 상대적으로 많다
할인 조건에 따른 할인정책이 바뀐다면??
1. 코드스테이츠 수강생에게 고정금액할인을 , 청소년에게 고정비율 할인을 적용하도록 바뀐다면 여러군데를 수정해주어야한다.
public class CozDiscountCondition {
...
// 기존 코드 : private FixedRateDiscountPolicy fixedRateDiscountPolicy = new FixedRateDiscountPolicy(10);
// 변경된 코드 (예시일 뿐이니, 진짜로 변경하지는 마세요!)
private FixedAmountDiscountPolicy fixedAmountDiscountPolicy = new FixedAmountDiscountPolicy(500);
...
public int applyDiscount(int price) {
// 기존 코드 : return fixedRateDiscountPolicy.calculateDiscountedPrice(price);
// 변경된 코드 (예시일 뿐이니, 진짜로 변경하지는 마세요!)
return fixedAmountDiscountPolicy.calculateDiscountedPrice(price);
}
}
public class KidDiscountCondition {
...
// 기존 코드 : private FixedAmountDiscountPolicy fixedAmountDiscountPolicy = new FixedAmountDiscountPolicy(500);
// 변경된 코드 (예시일 뿐이니, 진짜로 변경하지는 마세요!)
private FixedRateDiscountPolicy fixedRateDiscountPolicy = new FixedRateDiscountPolicy(10);
...
public int applyDiscount(int price) {
// 기존 코드 : return fixedAmountDiscountPolicy.calculateDiscountedPrice(price);
// 변경된 코드 (예시일 뿐이니, 진짜로 변경하지는 마세요!)
return fixedRateDiscountPolicy.calculateDiscountedPrice(price);
}
}
2. 새로운 할인 이벤트를 여는 경우
백엔드 수료생대상으로 할인이벤트를 연다면?
-CozBackEndDiscountCondition 클래스 정의
- Order에서 인스턴스생성하는 코드 추가 / checkDiscountCondition()을 호출하는 코드 추가 / applyDiscount()를 호출하는 코드 추가
클래스 정의는 필연적이지만
할인조건을 추가했을뿐인데 주문과 관련된 Order에 코드추가해야하는것은 기존 코드에 영향을 준다
public void makeOrder() {
CozDiscountCondition cozDiscountCondition = new CozDiscountCondition();
KidDiscountCondition kidDiscountCondition = new KidDiscountCondition();
// 아래 코드를 추가해야 합니다. (예시일 뿐이니 진짜로 추가하지는 마세요)
CozBackEndDiscountCondition cozBackEndDiscountCondition = new CozBackEndDiscountCondition();
cozDiscountCondition.checkDiscountCondition();
kidDiscountCondition.checkDiscountCondition();
// 아래 코드를 추가해야 합니다. (예시일 뿐이니 진짜로 추가하지는 마세요)
cozBackEndDiscountCondition.checkDiscountCondition();
int totalPrice = cart.calculateTotalPrice();
int finalPrice = totalPrice;
if (cozDiscountCondition.isSatisfied()) finalPrice = cozDiscountCondition.applyDiscount(finalPrice);
if (kidDiscountCondition.isSatisfied()) finalPrice = kidDiscountCondition.applyDiscount(finalPrice);
// 아래 코드를 추가해야 합니다. (예시일 뿐이니 진짜로 추가하지는 마세요)
if (cozBackEndDiscountCondition.isSatisfied()) finalPrice = cozBackEndDiscountCondition.applyDiscount(finalPrice);
System.out.println("[📣] 주문이 완료되었습니다. ");
System.out.println("[📣] 주문 내역은 다음과 같습니다. ");
System.out.println("-".repeat(60));
cart.printCartItemDetails();
System.out.println("-".repeat(60));
System.out.printf("금액 합계 : %d원\n", totalPrice);
System.out.printf("할인 적용 금액 : %d원\n", finalPrice); // 추가
'실습👁️🗨️ > 연습' 카테고리의 다른 글
BurgerQueen 주문 프로그램 만들기 5 (0) | 2023.10.29 |
---|---|
BurgerQueen 주문 프로그램 만들기 3 (0) | 2023.10.28 |
BurgerQueen 주문 프로그램 만들기 2 (0) | 2023.10.28 |
BurgerQueen 주문 프로그램 만들기 1 (0) | 2023.10.27 |
김밥 키오스크 + (0) | 2023.10.25 |