Product 클래스는 각 상품에 관한 상품명, 가격, 설명, 재고수량 정보를 관리한다.
※ 클래스 Product와 List의 역할과 타입이 다름을 주의해야 한다.
(도전 기능 - 25. 09. 25 추가)
2. 장바구니 및 주문하기 기능
장바구니와 연관된 동작은 Cart 클래스에서 관리하도록 한다.
Cart 클래스에서 변동된 내용은 Category 클래스에도 반영되어야 한다.
관리자 모드 진입 시 로직은 Administrator 클래스에서 진행된다.
관리자 모드의 동작들은 Administrator - Category 간 연계되어 수행된다.

작성했던 모든 속성을 싹 지우고 List만 작성했다.
그리고 아래에 리스트에 내용을 입력하는 메서드를 사용하는 방식으로 수정했다.
.add()를 사용하면 요소를 하나만 추가할 수 있기 때문에 여러 코드를 작성해야 한다. 빠르게 여러 element를 삽입할 수 있는 방법이 없을까 찾아보다가 Collectios.addAll()을 찾았다.
List와 다른 List 안의 내용을 합쳐서 하나의 리스트로 만들고 싶을 때는 두
가지 방법이 있다.
두 방법 중에 어느 걸 고를지는 상황에 따라 효율이 달라진다. 추가할 데이터가 다양할 경우에는 Collections.addAll()이 따로 List 변환이 필요없을 것이고, 이미 리스트 형태로 선언된 상황이라면 List.addAll()을 사용해도 괜찮을 것이다.
단 둘의 연산 과정이 다르니 그 점을 주의해서 취사 선택해야 한다.
List.addAll()은 () 안의 List를 받아서 박스 포장을 열고 객체를 추가하는 형태
Collections.addAll()은 () 안의 객체를 직접 받아서 추가하는 형태
라고 이해했다.
→ 지금 내 경우, List 형태가 아닌 객체들(name, price, description, quantity)을 추가해야 하기 때문에 연산 과정이 적은(?) Collections.addAll()을 사용해 오류를 해결했다.
그런데
변경한 List 형식에 맞춰 setter 메서드를 수정하고,
null이 안 나오도록 getter 메서드도 수정해서 겨우 정상적으로 출력되는걸 확인했는데...
생각해보니 사용자가 상품 정보를 등록할 일은 없지 않나??
나중에 장바구니 추가 같은 기능을 구현할 예정인 걸 보면 지금 작성 중인 코드는 사용자가 쓸 법한 기능이 아니었다.

결국 싹 다 갈아엎고 다시 만들어서 Lv 1까지 완료했다..
상단의 요구사항은 24일 아침에 다시 정리해서 수정하겠다ಥ_ಥ
어제에 이어 과제의 요구사항을 다시 살펴보고 처음부터 찬찬히 다시 해보기로 했다. 일단 작성했던 CommerceSystem 클래스는 전체 주석 처리해 놨다.
do {
System.out.println("[ 실시간 커머스 플랫폼 - 전자제품 ]");
for(int i=0; i<products.size(); i++) {
System.out.println((i+1) + ". " + products.get(i));
}
System.out.println("0. 종료 | 프로그램 종료\n재고 수량을 조회하고 싶은 상품의 번호를 입력해 주세요.");
int i = input.nextInt();
if(i==0) {
break;
}
else products.get(i-1);
}while(!input.next().equals("0"));
1. 상세 이슈와 원인
코드 하단의 i라는 변수를 int 형으로 입력을 받기로 했는데 콘솔에서 Enter 키를 눌러도 제대로 입력 처리가 되지 않았다.
int i에 사용한 nextInt()와 그 아래에 while의 조건란에 작성된 next() 메서드의 동작 방식이 원인이다.
2. 원인 파헤치기(Scanner 메서드)
입력된 값을 int 형으로 받을 수 있다. 이 때 사용자가 [입력값을 작성 → Enter 키를 누르기] 과정으로 콘솔에서 입력을 할텐데, nextInt()는 Enter 키를 누르기 전의 입력값만 받는다. 그러면 사용자가 누른 Enter 키, 즉 개행문자(\n)는 받아주는 곳 없이 버퍼에 남아있는 상태가 된다.
next() 메서드는 입력값에서 공백이 나오기 전까지의 입력값을 받는다. 얘도 마찬가지로 개행문자를 포함하지 않고 값을 입력받기 때문에 버퍼에 "\n"가 남게 된다.
지금 내 코드에는 둘 다 Enter 키 입력으로 인한 개행문자가 버퍼에 남아있어 아무리 Enter를 눌러도 다음 단계로 진행되지 않았던 것이다.
3. 해결방법
: 개행문자를 포함하는 한 라인의 입력값을 읽고 '\n'를 제외한 나머지 내용만 return 해주는 메서드
일단 하단의 next() 메서드를 개행문자까지 받아주는 nextLine() 메서드로 수정했다.

else 문이 동작하지 않는 건 제껴두고 입력이 제대로 이뤄지는 걸 확인했다.
→ else 문의 원인은 코드를 보면 알 수 있듯...값만 불러오고 출력을 안했다. System.out.println으로 출력하자 의도한대로 내용이 나오는 걸 확인했다.
[ 실시간 커머스 플랫폼 메인 ]
1. 전자제품
2. 의류
3. 음식
0. 종료 | 프로그램 종료
1 //← 입력
[Galaxy S25 | 1,200,000원 | 최신 안드로이드 스마트폰, iPhone 16 | 1,350,000원 | Apple의 최신 스마트폰, MacBook Pro | 2,400,000원 | M3 칩셋이 탑재된 노트북, AirPods Pro | 350,000원 | 노이즈 캔슬링 무선 이어폰]
0. 뒤로가기
문제 구간의 명령문 형태
System.out.println(Category.CLOTHES.getCategoryList());
- Category : Enum
- ELECTRONICS : (String name, List... products)
- getCategoryList() : List 반환
start() 함수 안에 출력 형태를 다듬어 반복문으로 출력하려니 코드가 너무 길어지고 객체 지향적이지 않은 것 같아서 따로 출력을 함수로 빼내기로 했다.
❗(소소한 트러블슈팅) 잘못된 변수 출력

오잉...재고가 줄어든 숫자만 보인다.
의도했던 출력 내용
주문이 완료되었습니다! 총 금액: 13500원
돼지국밥 재고가 34개 → 33개로 업데이트 되었습니다.
T-shirt 재고가 326개 → 325개로 업데이트 되었습니다.
코드를 살펴보니 둘 다 같은 Product 클래스의 getter로 값을 가져오고 있었다. 사소한 실수(●ˇ∀ˇ●)
재고수량을 감소시키기 전의 값을 따로 before 변수로 담아주고 출력할 때 확실하게 전/후 값을 구분해서 가져왔다.


캡처 이미지를 보면 상품명을 입력받기도 전에 오류가 나타나며 코드가 종료된다.
int index = input.nextInt();
Product p = null;
System.out.println("삭제할 상품명을 입력해 주세요:");
String name = input.nextLine();
for (Category c : Category.values()) {
p = c.findProduct(name);
if (p != null) {
break;
}
}
System.out.println("상품 정보: " + p.toString() + " | 재고: " + p.getQuantity() + "개");
의도했던 동작은 아래와 같다.
1. 문자열을 입력받음(name)
2. name과 같은 상품명을 가진 Product를 찾아서 반환해주는 findProduct 호출
3. 반환된 Product를 p에 삽입
4. (if)해당하는 Product를 찾으면 for문의 반복을 종료 (break;)
5. 하단에 p의 정보를 출력
상태를 보니 입력받기도 전에 for문으로 진행되어서 name을 갖고있는 Product 객체를 못 찾는게 원인으로 추정된다.
또...개행문자 버퍼 때문인가......?
맨 처음의 nextInt() 줄 밑에 개행분자를 버퍼에서 지워줄 nextLine()을 추가했다.
int index = input.nextInt();
input.nextLine();
Product p = null;
System.out.println("삭제할 상품명을 입력해 주세요:");
String name = input.nextLine();
for (Category c : Category.values()) {
p = c.findProduct(name);
if (p != null) {
break;
}
}
System.out.println("상품 정보: " + p.toString() + " | 재고: " + p.getQuantity() + "개");
프로그램을 실행해보자.

제대로 상품 입력과 조회가 되는 걸 확인했다.

489 → 452 개로 수정한건데 하단에 변경 안내문의 숫자가 엉뚱한 내용이 나온다.
동작은 바르게 잘 썼던 기억이 있는데 하루가 지났으니... 혹시 몰라 다시 수정한 상품 정보를 조회해봤다.

수정한 내용이 잘 반영되어있다.
그렇다면 무엇이 문제인가, 하고 출력문 부분을 자세히 보니\(〇_o)/
알고보니 위 내용을 복사+붙여넣기했더니 깜빡하고 변수를 안 바꿔놨다. 재고 수량이 아니라 가격 정보를 출력하고 있었던 것!
다른 요소들은 다 잘 바꿨는데 재고 수량만 안 바뀌었다. 테스트 입력값은 임의로 넣은 건데 우연히 잘 걸렸다. 각 동작에 맞는 변수를 사용하도록 제대로 고쳐줬다.

관리자 모드에서 Galaxy S25를 삭제해줬는데도 장바구니에 해당 상품이 그대로 남아있다. 1)삭제가 제대로 안 된 건지 2)장바구니에서만 안 지워진 건지 확인해봤다.

카테고리에서 상품 목록을 보니 Category에선 삭제가 정상적으로 이뤄졌다.
//(관리자 모드)Administrator Class
System.out.println("상품 정보: " + p.toString() + " | 재고: " + p.getQuantity() + "개");
System.out.println("위 상품을 완전히 삭제하시겠습니까?\n1. 예 2.아니오(관리자 모드로 돌아갑니다.)");
int c = input.nextInt(); //분기점을 구분하는 c
if(c == 1) { //예 선택 시
Category.removeProduct(index, p); // Category에서 해당 상품을 삭제
Cart cart = new Cart(); //
cart.removeProduct(p); // Cart에 있는 해당 상품(요소)을 삭제
}
else if(c == 2) { // 아니오 선택 시
return;
}
// (장바구니) Cart Class
public void removeProduct(Product product) {
this.cartProducts.remove(product); //List<Product> cartProducts
}
(원인) 장바구니를 조회해주는 메서드를 호출하는 곳은 CommerceSystem 클래스다. 그리고 장바구니에 들어있는 Product를 삭제하고 있는 곳은 Administrator 클래스다. 이 두 곳의 Cart 객체는 각각 선언된 별개의 객체다. 아무것도 담기지 않은 장바구니에서 삭제할 수 있는 게 있을리 없다...

장바구니에서 Product를 삭제한 뒤 Cart의 목록을 출력해본 결과다.
아무 내용도 없는 게 보인다.
(해결방법) Cart 정보가 연동되려면 어떻게 해야할까?
현재 CommerceSystem 클래스의 Cart 객체(본 코드에서는 cart)를 인수로 Administrator 클래스에서 받고 각 동작을 수행한 뒤 반환하면 된다.
public static Cart adminMode(Cart cart) 이렇게 추가해줬다.
그 외 연동되는 문장들을 수정했더니 성공적으로 삭제가 이뤄지는 걸 확인할 수 있었다.
4
아래와 같이 주문하시겠습니까?
[ 장바구니 내역 ]
Shirt | 10,000원 | 기본 하얀 와이셔츠 | 수량: 2개
WoolSweater | 34,000원 | 울 소재 스웨터 | 수량: 1개
Wide-pants | 27,000원 | 통 넓은 슬랙스 바지 | 수량: 1개
[ 총 주문 금액 ]
81000원
1. 주문 확정 2. 메인으로 돌아가기
2
[ 실시간 커머스 플랫폼 메인 ]
1. 전자제품
2. 의류
3. 음식
0. 종료 | 프로그램 종료
6. 관리자 모드
[ 주문 관리 ]
4. 장바구니 확인 | 장바구니를 확인 후 주문합니다.
5. 주문 취소 | 진행 중인 주문을 취소합니다.
6
관리자 비밀번호를 입력해 주세요:
admin123
[ 관리자 모드 ]
1. 상품 추가
2. 상품 수정
3. 상품 삭제
4. 전체 상품 현황
0. 메인으로 돌아가기
3
어느 카테고리의 상품을 삭제하시겠습니까?
1. 전자제품
2. 의류
3. 음식
2
삭제할 상품명을 입력해 주세요:
Shirt
상품 정보: Shirt | 10,000원 | 기본 하얀 와이셔츠 | 재고: 489개
위 상품을 완전히 삭제하시겠습니까?
1. 예 2.아니오(관리자 모드로 돌아갑니다.)
1
상품을 성공적으로 삭제하였습니다.
메인으로 돌아갑니다.
[ 실시간 커머스 플랫폼 메인 ]
1. 전자제품
2. 의류
3. 음식
0. 종료 | 프로그램 종료
6. 관리자 모드
[ 주문 관리 ]
4. 장바구니 확인 | 장바구니를 확인 후 주문합니다.
5. 주문 취소 | 진행 중인 주문을 취소합니다.
4
아래와 같이 주문하시겠습니까?
[ 장바구니 내역 ]
WoolSweater | 34,000원 | 울 소재 스웨터 | 수량: 1개
Wide-pants | 27,000원 | 통 넓은 슬랙스 바지 | 수량: 1개
[ 총 주문 금액 ]
61000원
1. 주문 확정 2. 메인으로 돌아가기
전체적으로 코드를 너무 한 곳에 몰아넣은 감이 있어서 다시 전체적으로 다듬을 필요가 있다. 메서드 종류가 너무 많고, 한 클래스에 너무 task가 많이 집중되어 있다. 주석을 추가해 가면서 작성했던 메서드를 정리(병합, 삭제, 수정 등등)해봐야겠다.